반응형
Spring Boot AutoConfiguration
- 스프링 부트가 클래스패스, 환경, 설정 등을 분석해 필요한 Bean을 자동으로 구성
- 개발자는 복잡한 환경설정 없이 바로 애플리케이션 개발에 집중할 수 있다.
- 보편적으로 많이 사용하는 설정을 미리 제공
- spring-boot-starter-data-jpa 의존성을 추가하면 최소한의 DB 접속 정보만 입력하면 자동으로 DataSource, EntityManager, 트랜잭션 매니저 등이 설정된다.
- 설정 실수를 줄이고 빠른 개발이 가능
자동 설정의 동작 원리
- Spring Boot 프로젝트를 생성할 때 만들어진 클래스에서 볼 수 있는 @SpringBootApplication 애너테이션
- 이 애너테이션에 포함된 @EnableAutoConfiguration
@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 {
// ...
}
- 이를 통해 내부적으로 다양한 자동 설정 클래스들이 등록됨
@Import(AutoConfigurationImportSelector.class) // (1)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
- @Import(AutoConfigurationImportSelector.class) 을 등록한다.
- AutoConfigurationImportSelector는 DeferredImportSelector를 구현한 클래스
- 자동설정 클래스들을 찾아 스프링 컨테이너에 등록한다.
- AutoConfigurationImportSelector는 DeferredImportSelector를 구현한 클래스
// AutoConfigurationImportSelector.java
// 파일에 저장된 자동 설정 클래스목록을 가져온다.
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = ImportCandidates.load(AutoConfiguration.class, getBeanClassLoader())
.getCandidates();
Assert.notEmpty(configurations,
"No auto configuration classes found in "
+ "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}
// 그리고 등록한다.
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
- META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 에서 확인 가능
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration
// ...
- 스프링 부트가 시작될 때 해당 파일을 읽어 자동 설정 클래스를 로딩한다
자동 설정의 조건
- 수많은 설정 내용들을 포함하고 있는데, 모두 동작하는건아니다
- 자동설정 클래스는 로딩되지만 내부에 설정된 조건에 따라 실행여부 결정
- 내부조건이 충독되어야 자동설정 클래스가 실행되며 다음 조건들이 설정
- 특정 JAR 라이브러리가 클래스패스에 포함되면 자동 설정이 동작한다.
- 특정 스프링 빈이 있으면 자동 설정이 동작한다.
- 특정 스프링 빈이 없으면 자동 설정이 동작한다.
- 프로퍼티 파일에 특정 변수 값이 있으면 자동 설정이 동작한다.
- 이런 조건을 설정할 수 있는 조건 애너테이션들이 존재한다. Conditional이라는 머리말 사용
- @ConditionalOnBean
- @ConditionalOnMissingBean
- @ConditionalOnClass : 클래스패스에 설저오딘 클래스가 있으면 kwehd 설정
- @ConditionalOnProperty
- @ConditionalOnWebApplication : 웹 어플리케이션이면 자동 설정. 타입도 지정 가능(리액티브 웹 애플리케이션인지)
- AutoConfiguration.imports 에 있던 클래스 중 하나를 확인해보면?
- @ContditionalOnProperty로 해당 프로퍼티 여부에 따라 설정 여부를 결정하고 있다.
@AutoConfiguration
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {
}
- Spring Boot 자동설정은 개발자가 최소한의 설정만으로 다양한 기능을 빠르게 사용할 수 있도록 해주는 강력한 기능
- @ConditionalOn 을 많이 봤었는데 이렇게 사용하는 거구나하고 좀 더 이해할 수 있었다.
- 라이브러리를 만들고 이걸 자동설정하는걸 직접 해보고 싶다.
반응형