Spring/Spring Boot
Spring Boot 자동 구성과 조건(@EnableAutoConfiguration)
helloJosh
2024. 7. 30. 00:57
@EnableAutoConfiguration
이 어노테이션도 참 중요한 역할을 하는데, 역할은 현재가지고 있는 의존성을 체크해서 특정 클래스들을 로드하는 역할을 한다.
쉽게 설명하자면 Servlet관련된 의존성이 있으면 Servlet.class를 불러오고, Web-starter가 있으면 DispatcherServlet.class, WebMvcConfgiurer.class를 불러오는 기능이다. WebFlux 의존성이 있으면 webflux 관련된 클래스를 불러온다.
그래서 참고로! webflux 의존성이랑 web-starter의존성이 겹치면 에러가 나는 이유기도하다.
구현은 @Conditional이라는 어노테이션으로 만들어져있다.
구분 | 내용 | 비고 |
@ConditionalOnWebApplication | 프로젝트가 웹 애플리케이션이면 설정 동작 | |
@ConditionalOnBean | 해당Bean이 Context에 존재하면 동작 | Auto configuration only |
@ConditionalOnMissingBean | 해당Bean이 Context에 존재하지 않으면 동작 | Auto configuration only |
@ConditionalOnClass | 해당 클래스가 존재하면 자동설정 등록 | |
@ConditionalOnMissingClass | 해당 클래스가 존재하지 않으면 자동 | |
@ConditionalOnResource | 자원이(file 등) 존재하면 동작 | |
@ConditionalOnProperty | 프로퍼티가 존재하면 동작 | |
@ConditionalOnJava | JVM 버전에 따라 동작여부 결정 | |
@ConditionalOnWarDeployment | 전통적인 war 배포 방식에서만 동작 | |
@ConditionalOnExpression | SpEL 의 결과에 따라 동작여부 결정 |
이러한 빈 조건으로 class를 불러오거나 안불러올수있다.
스프링 쓰면서 한번도 사용해본 적은 없지만 알아둬서 나쁠건 없다고 생각한다....
코드 흐름
이것도 밑의 코드를 따라가면 AutoConfigurationImportSelector 는 META-INF/spring/%s.imports 경로의 파일을 해석해서 해당하는 클래스를 로드하려고 시도한다.
@Import(AutoConfigurationImportSelector.class)
ConfigurationClassParser.doProcessConfigurationClass()
ConfigurationClassParser.processImports()
AutoConfigurationImportSelector.selectImports()
AutoConfigurationImportSelector.selectImports()
AutoConfigurationImportSelector.getCandidateConfigurations()
ImportCandidates.load()
ImportCandidates.LOCATION
그리고 org.springframework.boot.autoconfigure.AutoConfiguration.imports 에는 여러가지 중에 아래 클래스들이 있고
...
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration
...
이중에 WebMvcAutoConfiguration.java를 들어가면 @Condition에 관련된 어노테이션이 들어가있는 것을 알 수 있다.
@AutoConfiguration(after = { DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
ValidationAutoConfiguration.class })
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@ImportRuntimeHints(WebResourcesRuntimeHints.class)
public class WebMvcAutoConfiguration {
// 중략..
}