2024. 10. 18. 16:47ㆍSpring Boot/Spring Boot Auto Configuration
ConfigurationClassPostProcessor
는 스프링 프레임워크에서 매우 중요한 역할을 하는 클래스 중 하나로, @Configuration을 기반으로 하는 Java 기반의 설정 클래스를 처리하고 관리하는 핵심 빈 팩토리 후처리기(BeanFactoryPostProcessor)입니다. 이 클래스는 주로 빈 정의를 읽고, 분석하며, 이를 바탕으로 빈을 등록하는 과정을 수행합니다. 특히 Spring 3.0 이후 Java 기반 설정 클래스가 도입되면서 더욱 중요한 역할을 하게 되었습니다.
1. 주요 역할
ConfigurationClassPostProcessor
는 스프링에서 애노테이션 기반 설정을 처리하는 과정에서 중요한 역할을 합니다. 주요 작업은 다음과 같습니다:
- @Configuration, @ComponentScan, @Import, @Bean 등의 애노테이션을 처리
- 빈 정의를 등록 및 수정
- 중복 빈 정의를 피하기 위한 CGLIB 프록시 기반의 메커니즘 제공
- 스프링의 Java 설정 파일을 처리하고, 이를 기반으로 추가적인 빈 정의를 생성
2. 동작 원리
이 클래스는 BeanFactoryPostProcessor
를 구현하고 있기 때문에, 스프링 컨테이너가 초기화되는 과정 중에 실행됩니다. 일반적으로 애플리케이션 컨텍스트가 시작될 때, 스프링은 ConfigurationClassPostProcessor
를 사용하여 @Configuration이 적용된 클래스를 분석하고, 해당 설정 클래스에서 정의한 빈 메타데이터를 기반으로 빈 정의를 등록하게 됩니다.
3. 주요 메서드 및 흐름
3.1 postProcessBeanDefinitionRegistry()
이 메서드는 스프링의 초기화 과정에서 빈 정의 레지스트리(BeanDefinitionRegistry)에 접근하여, @Configuration 클래스를 찾고 처리하는 역할을 합니다.
- @Configuration 클래스 탐색:
postProcessBeanDefinitionRegistry()
는BeanDefinitionRegistry
에서 모든 빈 정의를 검색하며, 이 중 @Configuration 애노테이션이 적용된 클래스를 찾습니다. - 빈 정의 추가 및 수정: 찾은 설정 클래스에 대해 @Bean 메서드와 같은 빈 정의를 분석하여, 이를
BeanDefinition
으로 변환한 후 레지스트리에 등록합니다.
3.2 processConfigBeanDefinitions()
이 메서드는 실제로 @Configuration 클래스를 처리하는 주요 메서드입니다. 다음과 같은 작업을 수행합니다:
- @Configuration 클래스 분석:
processConfigBeanDefinitions()
는 @Configuration이 적용된 클래스를 분석하여 @Bean, @ComponentScan, @Import 등을 처리합니다. - 빈 정의 등록: 메서드 내부에서 ConfigurationClassParser를 사용하여, Java 설정 클래스에서 정의한 @Bean 메서드 등을 분석하고 이를 기반으로 새로운 빈 정의를 레지스트리에 추가합니다.
3.3 enhanceConfigurationClasses()
이 메서드는 CGLIB 프록시를 사용하여 @Configuration 클래스를 향상시킵니다. CGLIB를 사용하는 이유는 빈 메서드 간의 상호 참조 문제를 해결하기 위해서입니다. 기본적으로 @Bean 메서드를 호출할 때 직접 호출되지 않고 프록시를 통해 호출되도록 함으로써, 싱글톤 빈 보장을 위해 동작합니다.
4. 프록시 기반 처리
스프링은 @Configuration 클래스에서 정의한 @Bean 메서드를 호출할 때 CGLIB 프록시를 통해 메서드를 호출합니다. 이는 같은 클래스 내에서 서로 다른 @Bean 메서드를 호출할 때 새로운 인스턴스를 생성하지 않고 이미 스프링 컨테이너에 등록된 빈을 반환하기 위해서입니다.
예를 들어, 같은 @Configuration 클래스에서 두 개의 @Bean 메서드가 상호 참조하는 경우, 이 프록시 메커니즘을 통해 싱글톤 컨테이너의 일관성을 유지합니다.
5. ConfigurationClassParser
ConfigurationClassPostProcessor
는 내부적으로 ConfigurationClassParser를 사용하여 설정 클래스를 파싱합니다. 이 클래스는 여러 애노테이션을 분석하고 처리하여, 해당 애노테이션에 정의된 빈 정의들을 파싱 트리 형태로 구성합니다.
- @Import 처리:
ConfigurationClassParser
는 @Import 애노테이션을 분석하여 다른 설정 클래스나 임포트된 빈 설정도 함께 처리합니다. - @ComponentScan 처리: 패키지 스캔을 통해 컴포넌트 클래스들을 찾아내어 빈으로 등록할 수 있도록 돕습니다.
6. 동작 과정 요약
- @Configuration 클래스 탐색:
postProcessBeanDefinitionRegistry()
에서 애플리케이션 컨텍스트 내에서 @Configuration이 적용된 클래스를 찾습니다. - 빈 정의 분석:
processConfigBeanDefinitions()
에서 @Bean 메서드, @ComponentScan, @Import 등을 분석하여 빈 정의를 생성합니다. - 빈 등록: 분석한 빈 정의를
BeanDefinitionRegistry
에 등록합니다. - 프록시 생성:
enhanceConfigurationClasses()
에서 CGLIB 프록시를 사용하여 @Bean 메서드 호출 시 동작 방식을 제어합니다. - 완료: 빈 팩토리 후처리기를 완료하고 나면, @Bean 메서드로 정의된 빈이 스프링 컨테이너에 등록되고 관리됩니다.
7. 확장성
ConfigurationClassPostProcessor
는 스프링의 확장 포인트로 사용될 수 있으며, 커스텀 BeanFactoryPostProcessor
와 결합하여 사용자 정의 설정 로직을 추가할 수도 있습니다. 예를 들어, 특정 조건에 따라 추가적인 빈 정의를 등록하거나, 기존의 빈 정의를 수정할 수 있습니다.
8. 예시 코드 흐름
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyServiceImpl();
}
@Bean
public MyRepository myRepository() {
return new MyRepositoryImpl();
}
}
ConfigurationClassPostProcessor
가 실행되면서AppConfig
클래스가 설정 클래스로 인식됩니다.AppConfig
클래스 내의 @Bean 메서드인myService()
와myRepository()
가 파싱되어 BeanDefinition으로 등록됩니다.- 프록시 객체가 만들어져
AppConfig
클래스 내에서 빈을 호출할 때 싱글톤으로 관리되도록 보장합니다.
ConfigurationClassPostProcessor
는 스프링의 애노테이션 기반 설정을 위한 핵심 처리기로서, 설정 클래스의 메타데이터를 읽고, 이를 스프링의 빈 정의로 변환하여, 스프링 컨테이너가 애플리케이션을 실행하는 데 필요한 빈을 적절하게 관리하고 주입할 수 있도록 지원합니다.
'Spring Boot > Spring Boot Auto Configuration' 카테고리의 다른 글
Spring Boot Auto-Configuration (0) | 2024.10.18 |
---|---|
DefaultListableBeanFactory (1) | 2024.10.18 |
ConfigurationClassParser (0) | 2024.10.18 |
PostProcessorRegistrationDelegate (0) | 2024.10.18 |
AnnotationConfigServletWebServerApplicationContext (0) | 2024.10.18 |