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 {
	// 중략..
}