본 글은 공부만 하면 까먹을 것 같아서 정리하는 글입니다.
본 글은 인프런 백기선 강사님의 '스프링 부트-개념과 활용' 강좌에서 발췌한 내용들이 포함되어 있습니다.
스프링 부트 버전은 2.4.2 버전 입니다.
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
스프링 부트 프로젝트를 생성하면 가장 먼저 보이는 annotation이 @SpringBootApplication
입니다.
@SpringBootApplication
은 크게 3가지의 annotation으로 구성되어 있는데 아래와 같습니다.
@SpringBootConfiguration
@ComponentScan
@EnableAutoConfiguration
@SpringBootApplication = (@SpringBootConfiguration + @ComponentScan + @EnableAutoConfiguration )
클래스에 명시하는 annotation으로 클래스가 application의 환경설정을 제공한다고 알려줍니다.
대부분의 스프링 부트는 일반적인 경우에서
@SpringBootConfiguration
을 상속한@SpringBootApplication
을 통해 사용합니다.
basePackages
혹은 basePackageClass
에 별다른 값을 주지 않으면 @ComponentScan
annotation이 적용된 클래스의 패키지와 하위 패키지들을 대상으로 @Component
, @Repository
, @Service
, @Controller
, @RestController
annotation이 사용된 클래스에 대한 스캔을 수행합니다.
xml을 이용해 등록하거나
@Bean
을 사용하지 않고 간편하게 bean을 등록!
스프링 부트에서는 2단계를 거쳐 bean들이 등록됩니다.
1. @ComponentScan
2. @EnableAutoConfiguration
@ComponentScan
은 @Component
annotation을 사용한 클래스들을 bean으로 등록한다는 건 알겠는데, @EnableAutoConfiguration
을 사용할 때는 어떤 클래스가 bean으로 등록된다는 것일까요?
@EnableAutoConfigurationEnable
은 스프링 부트의 META-INF 파일을 읽어서 미리 정의된 설정파일(@Configuration
)을 자동으로 등록할 수 있게 합니다.
미리 정의된 설정파일을 찾아보겠습니다
스프링 부트 프로젝트에 추가된 의존성 중 spring-boot-autoconfigure
라는 의존성의 META-INF 파일 안 spring.factories
를 보면
org.springframework.boot.autoconfigure.EnableAutoConfiguration
라는 key 값과 AutoConfiguration
으로 끝나는 많은 value 값들이 있습니다. 이것들이 모두 기본으로 설정되어 있는 AutoConfiguration
입니다.
그 중에 한가지인 DispatcherServletAutoConfiguration
을 살펴보겠습니다.
// DispatcherServletAutoConfiguration.java
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(DispatcherServlet.class)
@AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)
public class DispatcherServletAutoConfiguration {
...
...
}
많은 annotation들이 사용되었지만 주목할 부분은 @Configuration
입니
다. 결국 DispatcherServletAutoConfiguration
도 bean을 설정하는 java 설정파일입니다.
spring.factories
안에autoconfigure.EnableAutoConfiguration
key에 대응하는 많은AutoConfiguration
클래스들이@EnableAutoConfiguration
의 대상이 되는 것 입니다.
그러나 모든 AutoConfiguration
들이 등록되는 것은 아닙니다.
DispatcherServletAutoConfiguration
파일을 보면 @ConditionalOnClass
,
@ConditionalOnMissingBean
과 같은 여러 조건들이 명시되어 있습니다.
이 조건들을 모두 만족해야 @EnablueAutoConfiguration
에 의해서 bean으로 등록이 되는 것 입니다.
// DispatcherServletAutoConfiguration.java
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(DispatcherServlet.class)
@AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)
public class DispatcherServletAutoConfiguration {
...
...
}
예를 들어 @ConditionalOnWebApplication(type = Type.SERVLET)
라는 부분을 보면 WebApplication
의 type
이 SERVLET
일때만 이 AutoConfiguration
이 등록이 됩니다.
만약 아래와 같이 WebAppliationType
을 NONE
으로 수정하고,
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication app=new SpringApplication(DemoApplication.class);
app.setWebApplicationType(WebApplicationType.NONE);
app.run(args);
}
}
AppRunner에서 DispatcherServlet
을 가져오려고 하면,
@Component
public class AppRunner implements ApplicationRunner {
@Autowired
private DispathcerServlet servlet;
@Override
public void run(ApplicationArguments args) throws Exception {
...
}
}
DispatcherServlet that could not be found.
이라는 오류를 출력합니다.
WebApplicationType
이 SERVLET
이 아니라 NONE
이기 때문에
DispatcherServletAutoConfiguration
이 자동으로 등록되지 않고 DispatcherServlet
도 bean으로 등록이 되지 않은 것 입니다.
물론 WebApplicationType
과 관련없는(@Conditional
조건을 사용하지 않은)
다른 AutoConfiguration
들은 자동으로 등록이 되겠죠?
@Conditional
을 통해서 특정한AutoConfiguration
이 자동으로 등록되고 등록되지 않는 것 입니다.