본문 바로가기
Spring

스프링 부트 AutoConfiguration 원리

by PROMISE_YOO 2022. 1. 15.

스프링 부트 AutoConfiguration 원리

 

 

@SpringBootApplication 어노테이션의 내부적으로 코드를 살펴보면 참 많은 것이 있습니다.

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
  @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
    ```이하생략```
}
  • @SpringBootConfiguration: 스프링 부트의 설정을 나타내는 어노테이션입니다. 스프링의 @Configuration을 대체하며 스프링 부트 전용 어노테이션입니다. 테스트 어노테이션을 사용할 때 계속 이 어노테이션을 찾기 때문에 스프링 부트에서는 필수 어노테이션입니다.
  • @EnableAutoConfiguration: 자동 설정의 핵심 어노테이션입니다. 클래스 경로에 지정된 내용을 기반으로 설정 자동화를 수행합니다.

  • @ComponentScan: basePackages 프로퍼티 값에 별도의 경로를 설정하지 않으면 해당 어노테이션이 위치한 패키지가 루트 경로가 됩니다.

 

이중 org/springframework/boot/autoconfigure 하위의 @EnableAutoConfiguration 어노테이션 코드입니다.

 

package org.springframework.boot.autoconfigure;

'''생략'''

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

 '''생략'''

}

 

@EnableAutoConfiguration 어노테이션 내부에 있는 @Import()이 자동 설정을 지원해주는 어노테이션입니다. AutoConfigurationImportSelector.class 를 import하고 있습니다.

 

 

AutoConfigurationImportSelector.class 코드입니다.

public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
		ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

	private static final AutoConfigurationEntry EMPTY_ENTRY = new AutoConfigurationEntry();

	private static final String[] NO_IMPORTS = {};

	private static final Log logger = LogFactory.getLog(AutoConfigurationImportSelector.class);

	private static final String PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE = "spring.autoconfigure.exclude";

	private ConfigurableListableBeanFactory beanFactory;

	private Environment environment;

	private ClassLoader beanClassLoader;

	private ResourceLoader resourceLoader;

	private ConfigurationClassFilter configurationClassFilter;

	@Override
	public String[] selectImports(AnnotationMetadata annotationMetadata) {
		if (!isEnabled(annotationMetadata)) {
			return NO_IMPORTS;
		}
		AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
		return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }
 }

 

selectImports 메소드를 통해  그리고 import할 목록을 String[] 타입으로 으로 리턴해줍니다. 

  1. selectImports() 메서드가 annotationMetadata를 선별하여 자동 설정할 빈을 결정합니다.
  2. getCandidateConfigurations() 메서드를 사용해 모든 후보빈을 불러옵니다.
    (이때 META-INF/spring.factories 에 정의된 자동 설정할 클래스들을 먼저 불러옵니다.)

 

 

정리를 해보자면 @EnableAutoConfiguration 어노테이션 내부에 있는 @Import() 어노테이션을 통해AutoConfigurationImportSelector.class 를 import하여 자동 설정을 지원해주는 원리입니다.

 


 

 

빈의 등록과 자동 설정에 필요한 파일입니다.

  • META-INF/spring.factories
    • 자동 설정 타깃 클래스 목록
    • 이곳에 선언된 클래스들이 @EnableConfiguration 사용 시 자동 설정 타깃이 됩니다.
    • 하위에 AutoConfigurations클래스가 있습니다.
  • META-INF/spring-configuration-matadata.json
    • 자동 설정에 사용할 프로퍼티 정의 파일
    • 미리 구현되어 있는 자동 설정에 프로퍼티만 주입시켜주면 됩니다.
    • 변경을 위해서는 application.properties 나 application.yml에 프로퍼티 값을 추가합니다.
  • org/springframework/boot/autoconfigure
    • 미리 구현해놓은 자동 설정 리스트
    • 모두 자바 설정 방식을 따릅니다.