Spring Boot Autoconfiguration
@SpringBootApplication
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Configuration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication {
/**
* Exclude specific auto-configuration classes such that they will never be applied.
* @return the classes to exclude
*/
Class<?>[] exclude() default {};
}
EnableAutoConfiguration
자동설정 관련한 어노테이션 특정 기준의 설정클래스를 로드
@Enable* 어노테이션
3.0에서는 잘 사용하지 않았다. 자바 Configuration 을 잘 사용하지 않았었다. 3.1로 넘어오면서 사용빈도가 높아진다.
예를 들어 EnableWebMvc 같은 어노테이션이 있다. EnableAspectJAutoProxy
@Import 와 함께 자신만의 모듈을 만들수 있다.
@EnableAutoConfiguration
스프링부트의 설정의 시작
@Import({ EnableAutoConfigurationImportSelector.class,
AutoConfigurationPackages.Registrar.class })
public @interface EnableAutoConfiguration {
/**
* Exclude specific auto-configuration classes such that they will never be applied.
* @return the classes to exclude
*/
Class<?>[] exclude() default {};
}
@EnableAutoConfigurationImportSelector
제일 핵심인 코드
DeferredImportSelector 이 어노테이션을 통해서 설정정보를 가져온다.
@Order(Ordered.LOWEST_PRECEDENCE)
class EnableAutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware {
private ClassLoader beanClassLoader;
private ResourceLoader resourceLoader;
/*
* 문자열 배열의 의미는 package와 class명 정보를 가져온다.
*/
@Override
public String[] selectImports(AnnotationMetadata metadata) {
try {
AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(EnableAutoConfiguration.class.getName(), true));
// Find all possible auto configuration classes, filtering duplicates
List<String> factories = new ArrayList<String>(new LinkedHashSet<String>(SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class, this.beanClassLoader)));
// Remove those specifically disabled
factories.removeAll(Arrays.asList(attributes.getStringArray("exclude")));
// Sort
factories = new AutoConfigurationSorter(this.resourceLoader).getInPriorityOrder(factories);
return factories.toArray(new String[factories.size()]);
}
catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
}
spring.factories
설정리스트의 보관소 스프링 개발자들이 만들어놓은 노가다 작업
/META-INF/spring.factories 파일에 이미 정의 되어있다. 해당 파일은 boot-Autoconfiguration.jar 파일에 존재한다.
모든 클래스는 로딩이 되나 스프링 컨테이너에 올라가지는 않는다. 메모리에 올라가면 상당이 느려질 수 있다. @Conditional 이라는 옵션을 통해서 조건적으로 Bean에 등록한다. Spring 4.x.x 에서부터 지원하기 시작하는 어노테이션 그래서 스프링은 4.x.x 대부터 스프링부트를 사용할 수 있다.
# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer
# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
@Conditional 예제
특정 Bean을 등록할 때 특정 환경에서만 등록하고 싶다.
@Bean
@Conditional(Phase.class)
public CommandLineRunner ....
class Phase implements Condition {
public boolean match
}
@Profile 어노테이션
대표적인 Conditional 에 대한 예제