Backend/spring
Spring Boot 자동 구성
jinmook
2023. 7. 6. 01:22
이번 글은 인프런 김영한님 강의 중 스프링 부트 - 핵심 원리와 활용 강의를 듣고 스프링에서 제공해주는 자동 구성에 관해 정리한 글입니다.
스프링 부트 - 핵심 원리와 활용 - 인프런 | 강의
실무에 필요한 스프링 부트는 이 강의 하나로 모두 정리해드립니다., 백엔드 개발자를 위한 스프링 부트 끝판왕! 실무에 필요한 내용을 모두 담았습니다. [임베딩 영상] 김영한의 스프링 완전
www.inflearn.com
@Conditional
- 어떤 bean configuration 클래스가 특정 조건일 때만 해당 기능이 활성화 되도록 할 수 있습니다.
- 예를 들어 개발 서버에서 확인 용도로만 해당 기능을 사용하고, 운영 서버에서는 해당 기능을 사용하지 않는 것입니다.
- 이때 사용하는 기능이 @Conditional 어노테이션 입니다.
이 기능을 사용하기 위해서는 Condition 인터페이스를 구현해야 합니다.
package org.springframework.context.annotation;
public interface Condition {
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
- matches() 메서드가 true 를 반환하면 조건에 만족하고 동작하며, false를 반환하면 동작하지 않습니다.
- ConditionContext : 스프링 컨테이너, 환경 정보등을 담고 있습니다.
- AnnotatedTypeMetadata : 애노테이션 메타 정보를 담고 있습니다.
만약 위 인터페이스를 구현한 MemoryCondition 클래스가 있다면 @Conditional(MemoryCondition.class) 어노테이션을 Config 클래스에 작성하여 MemoryCondition 클래스의 matches 메서드의 결과의 따라 해당 설정을 진행하도록 할 수 있습니다.
스프링에서는 @ConditionalOnXxx 어노테이션을 이미 제공하고 있다
- ConditionalOnClass, ConditionalOnMissingClass : 클래스가 있는 경우 동작한다 / 반대
- ConditionalOnBean, ConditionalOnMissingBean : 빈이 등록되어 있는 경우 동작한다 / 반대
- ConditionalOnProperty : 환경 정보가 있는 경우 동작한다.
- ConditionalOnResource : 리소스가 있는 경우 동작한다.
- ConditionalOnWebApplication, ConditionalOnNotWebApplication : 웹 애플리케이션인 경우 동작한다.
- ConditionalOnExpression : SpEL 표현식에 만족하는 경우 동작한다.
Conditional 자체는 스프링 부트가 아니라 스프링 프레임워크의 기능이다. 스프링 부트는 이 기능을 확장해서 @ConditionalOnXxx 를 제공한다.
우리가 만든 라이브러리를 직접 프로젝트에 사용해보자
- 위에서 만든 jar 파일을 직접 build.gradle에 추가한다. 이때 files의 라이브러리 위치를 작성할 수 있습니다.
dependencies {
implementation files('libs/memory-v1.jar') //추가
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
이제부터 자동 구성 라이브러리를 만들어보자
- @AutoConfiguration : 스프링 부트가 제공하는 자동 구성 기능을 적용할 때 사용하는 어노테이션입니다.
- @ConditionalOnProperty : memory=on 이라는 환경 정보가 있을 때 스프링 빈을 등록한다, 라이브러리를 가지고 있더라도 상황에 따라 해당 기능을 켜고 끌 수 있게 유연한 기능을 제공합니다.
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
@AutoConfiguration
@ConditionalOnProperty(name = "memory", havingValue = "on")
public class MemoryAutoConfig {
@Bean
public MemoryController memoryController() {
return new MemoryController(memoryFinder());
}
@Bean
public MemoryFinder memoryFinder() {
return new MemoryFinder();
}
}
[ 자동 구성 대상 지정 ]
- 스프링 부트 자동 구성을 적용하려면, 다음 파일에 자동 구성 대상을 꼭 지정해주어야 합니다.
파일 생성
src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiuration.imports
org.springframework.boot.autoconfigure.AutoConfiuration.imports 파일 내용
memory.MemoryAutoConfig
- 앞서 만든 자동 구성인 memory.MemoryAutoConfig 를 패키지를 포함해서 지정해줍니다.
- 스프링 부트는 시작 시점에 org.springramework.boot.autoconfigure.AutoConfigration.imports 의 정보를 읽어서 자동 구성으로 사용하며, 따라서 내부에 있는 MemoryAutoConfig가 자동으로 실행됩니다.
[ 스프링 부트의 자동 구성 동작 원리 순서 ]
@SpringBootApplication → @EnableAutoConfiguration → @Import(AutoConfigurationImportSelector.class)
@SpringBootApplication 코드를 보면
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes =
TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes =
AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {...}
여기서 중요한 것은 @EnableAutoConfiguration 어노테이션이다.
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {...}
- AutoConfigurationImportSelector는 ImportSelector의 구현체이므로 설정 정보를 동적으로 설정할 수 있습니다.
- 따라서 실제로 이 코드를 통해 모든 라이브러리에 있는 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 파일을 확인합니다.
자동 구성을 언제 사용하는가
- AutoConfiguration은 라이브러리를 만들어서 제공할 때 사용하고, 그 외에는 사용하는 일이 거의 없다.
- 하지만 보통 외부 이미 만들어진 라이브러리를 가져다 사용하지, 라이브러리를 만들어서 제공하는 경우는 매우 드룰다.
- 하지만 자동 구성을 알아야 하는 진짜 이유는 개발을 진행 하다보면 특정 빈들이 어떻게 등록된 것인지 확인이 필요할 때가 있다. 그래야 문제가 발생했을 때 대처가 가능하기 때문에 자동 구성의 원리를 알고 넘어가도록 하자