반응형
자동설정
- 자동설정은 스프링 부트의 장점이며 매우 중요한 역할.
- 스프링 부트 자동 설정은 web, h2, jdbc 등 여러개의 자동설정을 제공한다.
- h2 의존성이 클래스 경로에 존재한다면 자동으로 인메모리 데이터베이스에 접근한다.
자동환경설정 어노테이션
- 기존의 스프링 프레임워크를 사용했다면 의존성을 일일이 bean으로 설정했어야 한다.
- 스프링 부트는 관련 의존성을 스타터라는 묶음으로 제공하며 수동 설정을 지양한다.
@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 {
...
}
@SpringBootApplication : 스프링 부트의 설정을 나타내는 어노테이션
- 스프링의 @Configuration을 대체하며 스프링부트 전용으로 사용한다.
@EnableAutoConfiguration: 자동설정의 핵심 어노테이션
- 클래스 경로에 지정된 내용을 기반으로 설정 자동화를 수행
- 특정한 설정값을 추가하지 않을 경우 기본값으로 설정
@ComponentScan: 특정 패키지 경로를 기반으로 @Configuration에서 사용할 @Component 설정 클래스를 찾음
- @ComponentScan의 basePackages 프로퍼티 값에 별도의 경로를 설정하지 않으면 @ComponentScan이 위치한 패키지가 루트 경로로 설정됨
@SpringBootApplication = @SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan 조합
@EnableAutoConfiguration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
...
}
- 자동 설정을 지원해주는 어노테이션은 @Import(AutoConfigurationImportSelector.class)이다.
AutoConfigurationImportSelector 클래스
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
AnnotationAttributes attributes = getAttributes(annotationMetadata);
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
configurations = removeDuplicates(configurations);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = getConfigurationClassFilter().filter(configurations);
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}
- AutoConfigurationImportSelector 클래스는 DeferredImportSelector 인터페이스를 구현한 클래스로 오버라이드 받은 selectImports() 메서드가 자동 설정할 빈을 결정한다.
- getCandidateConfigurations() 메서드를 통해 META-INF/spring.factories에 정의된 자동 설정할 클래스를 먼저 불러온다.
- 스프링 부트 스타터를 여러개 등록하여 사용할 경우 내부에 중복된 빈이 설정될 경우가 빈번한데, 이러한 경우 제외할 설정(getExclusions())과 중복된 설정(removeDuplicates())을 제외시킨다.
빈의 등록과 자동 설정에 필요한 파일
META-INF/spring.factories: 자동 설정 타킷 클래스 목록
- 이곳에 선언되어 있는 클래스들이 @EnableAutoConfiguration 사용시 자동 설정 타깃이 된다.
META-INF/spring-configuration-metadata.json: 자동 설정에 사용할 프로퍼티 정의 파일 - 미리 구현되어 있는 자동 설정에 프로퍼티만 주입시켜주면된다.
- 별도의 환경 설정은 필요없다.
org/springframework/boot/autoconfigure: 미리 구현해놓은 자동 설정 리스트 - 이름은 '{특정설정의 이름}AutoConfiguration' 형식으로 지정되어 있으며 모두 자바 설정방식을 따르고 있다.
spring-boot-autoconfiguration에 미리 정의되어 있으며 지정된 프로퍼티 값을 사용하여 설정 클래스 내부의 값들을 변경할수 있다.
예) h2 자동설정
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration
{
"name": "spring.h2.console.path",
"type": "java.lang.String",
"description": "Path at which the console is available.",
"sourceType": "org.springframework.boot.autoconfigure.h2.H2ConsoleProperties",
"defaultValue": "\/h2-console"
},
- H2 기본값은 /h2-console
application.properties에서 h2 path변경
spring.h2.console.path=/h2-test
- 프로퍼티 값을 추가하는것만으로 자동환경 설정에 자동으로 적용된다.
자동 설정 어노테이션
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(WebServlet.class)
@ConditionalOnProperty(prefix = "spring.h2.console", name = "enabled", havingValue = "true", matchIfMissing = false)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
@EnableConfigurationProperties(H2ConsoleProperties.class)
public class H2ConsoleAutoConfiguration {
private static final Log logger = LogFactory.getLog(H2ConsoleAutoConfiguration.class);
@Bean
public ServletRegistrationBean<WebServlet> h2Console(H2ConsoleProperties properties,
ObjectProvider<DataSource> dataSource) {
String path = properties.getPath();
String urlMapping = path + (path.endsWith("/") ? "*" : "/*");
ServletRegistrationBean<WebServlet> registration = new ServletRegistrationBean<>(new WebServlet(), urlMapping);
H2ConsoleProperties.Settings settings = properties.getSettings();
if (settings.isTrace()) {
registration.addInitParameter("trace", "");
}
if (settings.isWebAllowOthers()) {
registration.addInitParameter("webAllowOthers", "");
}
dataSource.ifAvailable((available) -> {
try (Connection connection = available.getConnection()) {
logger.info("H2 console available at '" + path + "'. Database available at '"
+ connection.getMetaData().getURL() + "'");
}
catch (SQLException ex) {
// Continue
}
});
return registration;
}
}
@ConditionalOnWebApplication(type = Type.SERVLET)
- 웹 애플리케이션일 때
@ConditionalOnClass(WebServlet.class) - WebServlet.class가 클래스 경로에 있을때
@ConditionalOnProperty(prefix = "spring.h2.console", name = "enabled", havingValue = "true", matchIfMissing = false) - spring.h2.console.enabled값이 true일때
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
- DataSourceAutoConfiguration.class 클래스들이 적용한 이후에 해당 자동 설정 적용
@EnableConfigurationProperties(H2ConsoleProperties.class)
- 자동 설정 프로퍼티가 적용될때 H2ConsoleProperties 클래스 타입으로 H2 관련 프로퍼티 값을 매핑하여 사용하게 된다.
datasource.url=jdbc:h2:mem:testdb
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
##remote access
spring.h2.console.settings.web-allow-others=false
##enable trace output
spring.h2.console.settings.trace=false
컴파일에 포함되도록 H2 의존성을 설정.
compile('com.h2database:h2')
- H2 메모리 데이터베이스는 주로 테스트용으로만 쓰인다.
- 따라서 불필요하게 컴파일 의존성에 포함될 필요가 없다.
런타임에 의존성으로 설정
runtime('com.h2database:h2')
출저 - 처음배우는 스프링 부트 2
저자 - 김영재
반응형
'JAVA > Spring Boot' 카테고리의 다른 글
스프링 부트 기본설정 및 기본 테스트 (0) | 2021.06.04 |
---|---|
Swagger-UI url 변경 (0) | 2021.05.31 |
스프링 부트 기본-#1 (0) | 2020.10.15 |
Spring MyBatis사용 및 설정 (1) | 2020.10.13 |
메이븐 멀티 프로젝트 구성 (0) | 2020.09.04 |