[Spring] Auto Configuration 설정 시 사용되는 항목 알아보기
목차
- 프로젝트 구성
- progress-starter dependency
- progress-api dependency
- Auto Configuration 상세 설정정보
- 설정 코드
- 각 어노테이션별 역활
- 이외 어노테이션 역활
- 결론
1. 프로젝트 구성
필자는 아래와 같은 프로젝트 구성을 하였습니다.
[progress-starter dependency]
dependencies {
// Using only starter
testRuntimeOnly("com.h2database:h2")
// Using starter and module
api("org.springframework.boot:spring-boot-starter-data-rest")
api("org.springframework.boot:spring-boot-starter-validation")
api("org.springframework.boot:spring-boot-starter-actuator")
api("org.springframework.boot:spring-boot-starter-security")
api("org.springframework.boot:spring-boot-starter-data-jpa")
api("org.springframework.boot:spring-boot-starter-data-redis")
api("org.springframework.boot:spring-boot-starter-data-elasticsearch")
api("org.springframework.boot:spring-boot-starter-oauth2-resource-server")
api("org.springframework.boot:spring-boot-starter-cache")
api("org.springframework.boot:spring-boot-starter-webflux")
api("com.github.ben-manes.caffeine:caffeine")
api("io.micrometer:micrometer-tracing-bridge-brave")
api("io.zipkin.reporter2:zipkin-reporter-brave")
api("net.logstash.logback:logstash-logback-encoder:7.4")
api("io.netty:netty-resolver-dns-native-macos:4.1.94.Final:osx-aarch_64")
api("io.hypersistence:hypersistence-utils-hibernate-62:3.6.0")
}
[progress-api dependency]
dependencies {
implementation(project(":progress-starter"))
runtimeOnly("com.h2database:h2")
annotationProcessor("com.querydsl:querydsl-apt:${dependencyManagement.importedProperties["querydsl.version"]}:jakarta")// querydsl JPAAnnotationProcessor 사용 지정
annotationProcessor("jakarta.persistence:jakarta.persistence-api")// java.lang.NoClassDefFoundError(javax.annotation.Entity) 발생 대응
annotationProcessor("jakarta.annotation:jakarta.annotation-api")// java.lang.NoClassDefFoundError (javax.annotation.Generated) 발생 대응
// test
testImplementation(testFixtures(project(":progress-starter")))
}
progress-api가 progress-starter를 의존하는 구성입니다. (implementation(project(":progress-starter"))
spring boot stater와 같이 progress-starter에는 필요한 항목들을 Auto Configuration 설정을 하였습니다.
이 결과로 progress-api에서는progress-starter를 의존함으로써
progress-starter의 dependency로 추가 된 항목 중 Auto Configuration으로 등록 된 항목들이 자동으로 빈이 생성되어 사용할 수 있게 됩니다.
2. Auto Configuration 상세 설정정보
[설정코드]
@AutoConfiguration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnProperty(prefix = "woo.logging", name = "enabled", matchIfMissing = true)
@EnableConfigurationProperties(WooLoggingProperties.class)
public class WooLoggingAutoConfiguration {
@Bean
@ConditionalOnMissingBean(name = "loggingFilter", value = LoggingFilter.class)
public LoggingFilter loggingFilter() {
log.debug("### WooAutoconfigure Bean: '{}'", "loggingFilter");
return new LoggingFilter();
}
}
[각 어노테이션별 역활]
- @AutoConfiguration: 이 어노테이션은 이 클래스가 Spring Boot의 자동 구성의 일부임을 나타냅니다. 자동 구성 클래스는 특정 클래스나 속성의 존재 여부에 따라 응용 프로그램을 구성하는 역할을 합니다.
- @ConditionalOnWebApplication(type = Type.SERVLET): 이 어노테이션은 응용 프로그램이 서블릿 환경의 웹 응용 프로그램인 경우에만 자동 구성이 적용되도록 합니다.
- @ConditionalOnProperty(prefix = "woo.logging", name = "enabled", matchIfMissing = true): 이 어노테이션은 자동 구성이 적용되려면 "woo.logging" 접두사와 "enabled" 이름의 속성이 설정되어 있어야 합니다. 설정되어 있지 않은 경우 matchIfMissing = true로 인해 기본적으로 true로 간주됩니다.
- @EnableConfigurationProperties(WooLoggingProperties.class): 이 어노테이션은 지정된 클래스(WooLoggingProperties)에 대한 구성 속성 바인딩을 활성화합니다. 이를 통해 application.properties 또는 application.yml에 정의된 속성을 WooLoggingProperties 클래스에 바인딩할 수 있습니다.
- @Bean: 이 어노테이션은 Spring 컨텍스트에 빈을 선언하는 데 사용됩니다. @Bean이 달린 메서드는 빈을 생성하고 반환하는 역할을 합니다.
- @ConditionalOnMissingBean(name = "loggingFilter", value = LoggingFilter.class): 이 어노테이션은 "loggingFilter" 이름과 유형 LoggingFilter를 가진 기존 빈이 없는 경우에만 빈 생성 메서드가 실행되도록 합니다. 해당 이름과 유형의 빈이 이미 존재하면 이 메서드는 호출되지 않습니다.
요약하면, 이 자동 구성 클래스는 특정 조건(@ConditionalOnWebApplication, @ConditionalOnProperty)을 확인하여 활성화 여부를 결정합니다. 활성화되면 지정된 이름과 유형의 기존 빈이 없는 경우에만 빈(LoggingFilter)을 생성합니다. @EnableConfigurationProperties 어노테이션은 WooLoggingProperties 클래스에 속성을 바인딩하는 것을 가능하게 합니다.
[이외 어노테이션 역활]
@ConditionalOn으로 시작하는 여러 어노테이션이 Spring Boot에서 제공됩니다. 이 어노테이션들은 특정 조건이 충족될 때 빈 또는 설정이 적용되도록 하는 데 사용됩니다. 몇 가지 예시를 아래에 나열했습니다:
- @ConditionalOnClass: 특정 클래스가 클래스 패스에 존재할 때 조건을 만족시킵니다.
- @ConditionalOnMissingClass: 특정 클래스가 클래스 패스에 없을 때 조건을 만족시킵니다.
- @ConditionalOnBean: 특정 빈이 컨텍스트에 등록되어 있을 때 조건을 만족시킵니다.
- @ConditionalOnMissingBean: 특정 빈이 컨텍스트에 등록되어 있지 않을 때 조건을 만족시킵니다.
- @ConditionalOnExpression: SpEL(스프링 표현 언어) 표현식을 사용하여 조건을 만족시킵니다.
- @ConditionalOnJava: 특정 자바 버전 범위에 따라 조건을 만족시킵니다.
이러한 어노테이션들은 조건에 따라 빈이나 설정이 활성화되거나 비활성화되도록 할 수 있습니다. 개발자는 이러한 어노테이션들을 사용하여 어플리케이션의 구성을 유연하게 조절할 수 있습니다.
3. 결론
위의 코드는 Spring Boot의 커스텀 자동 구성 예제로, WooLoggingAutoConfiguration 클래스를 통해 특정 조건이 충족될 때 LoggingFilter 빈을 생성합니다. 이를 가능케 하는 여러 @ConditionalOn* 어노테이션들이 사용되었습니다. 자동 구성은 주로 프로젝트의 특정 기능을 활성화하거나 비활성화할 수 있는 강력한 도구 중 하나입니다.
이러한 구성들은 중앙 모듈역활로 자주 사용하는 기능들을 포함시키고 의존하는 하위 모듈에서는 on/off 설정으로 사용 할 수 있으며, 새로운 하위모듈을 추가 시 매우 간편하게 구성할 수 있는 장점이 있습니다.