@Configuration
1. 개요
1. 개요
@Configuration은 스프링 프레임워크에서 자바 기반 설정을 위해 사용되는 핵심 어노테이션이다. 이 어노테이션이 적용된 클래스는 스프링 IoC 컨테이너에게 빈(Bean)의 정의와 상호 의존 관계를 구성하는 메타데이터를 제공하는 구성 클래스의 역할을 한다.
기존에 널리 사용되던 XML 기반 설정 방식을 대체하기 위해 스프링 3.0에서 처음 도입되었다. 자바 코드를 이용해 빈을 선언하고 의존성 주입(DI)을 설정함으로써, 타입 안정성과 리팩토링의 편의성을 크게 향상시켰다. @Configuration 클래스 내부에서는 @Bean 어노테이션을 메서드에 적용하여 스프링 컨테이너가 관리할 객체를 직접 정의한다.
이 방식의 주요 장점은 컴파일 타임에 오류를 검출할 수 있으며, 복잡한 빈의 초기화 로직이나 조건부 빈 생성을 프로그래밍적으로 제어하기 쉽다는 점이다. 현대적인 스프링 부트 애플리케이션의 구성은 거의 대부분 이 @Configuration과 자바 기반 설정을 중심으로 이루어진다.
2. 역사
2. 역사
@Configuration 어노테이션은 스프링 프레임워크 3.0 버전에서 처음 도입되었다. 이는 기존의 XML 기반 빈 설정 방식을 대체하기 위한 자바 기반 설정 방식의 핵심 구성 요소로 등장했다. 스프링 2.5 버전까지는 애플리케이션 컨텍스트 내의 빈 정의와 의존성 주입을 주로 XML 파일을 통해 명시하는 것이 일반적이었다.
스프링 3.0은 자바 5 이상의 기능을 적극적으로 활용하며, 어노테이션 기반 설정을 강화하는 방향으로 발전했다. @Configuration의 등장은 개발자가 순수 자바 코드로 빈의 생성과 의존성 주입 로직을 완전히 표현할 수 있게 함으로써, 타입 안전성을 높이고 리팩토링을 용이하게 하는 중요한 전환점이 되었다. 이는 자바 기반 설정이라는 새로운 패러다임을 정립했다.
이후 스프링 4.0과 5.0을 거치면서 @Configuration 클래스는 람다 표현식 활용, 조건부 빈 등록을 위한 @Conditional 어노테이션과의 통합, 그리고 스프링 부트의 자동 구성 메커니즘의 기반이 되는 등 지속적으로 그 역할과 기능이 확장 및 정교화되었다. 현재는 XML 설정과 함께, 그리고 많은 경우 이를 대체하여 스프링 애플리케이션 구성의 표준 방식으로 자리 잡았다.
3. 기본 개념
3. 기본 개념
3.1. @Configuration 어노테이션의 역할
3.1. @Configuration 어노테이션의 역할
@Configuration 어노테이션의 핵심 역할은 스프링 프레임워크의 자바 기반 설정 방식을 가능하게 하는 것이다. 이 어노테이션이 적용된 클래스는 스프링 IoC 컨테이너에게 빈 설정 메타데이터를 제공하는 구성 클래스로 인식된다. 이는 전통적으로 사용되던 XML 기반 빈 설정 파일을 완전히 대체하는 현대적인 방식으로, 타입 안전성과 리팩토링 용이성에서 큰 장점을 가진다.
구체적으로 이 어노테이션의 역할은 @Bean 어노테이션과 함께 사용되는 메서드들을 통해 빈 (스프링)을 정의하고, 그들 간의 의존성 주입 관계를 구성하는 것이다. 컨테이너는 @Configuration 클래스를 처리하여 내부의 @Bean 메서드들을 호출하고, 그 반환 객체들을 애플리케이션 컨텍스트에 싱글톤 빈 (스프링)으로 등록한다. 이를 통해 개발자는 순수 자바 코드로 애플리케이션의 객체 그래프를 명시적으로 구성할 수 있다.
또한, @Configuration 클래스는 다른 빈 (스프링)을 주입받아 사용할 수 있으며, 빈 (스프링) 메서드 간의 호출을 통해 빈들 사이의 의존성을 설정할 수 있다. 이때 스프링은 CGLIB 라이브러리를 이용한 프록시를 적용하여 메서드 호출을 가로채고, 싱글톤 패턴을 보장하며 불필요한 객체 생성을 방지하는 중요한 기능을 수행한다.
3.2. @Bean 어노테이션과의 관계
3.2. @Bean 어노테이션과의 관계
@Configuration 어노테이션은 스프링 프레임워크의 자바 기반 설정 방식에서 빈을 정의하는 메타데이터를 제공하는 클래스를 표시한다. 이 어노테이션 자체만으로는 빈을 생성하지 않으며, 실제 빈을 정의하는 핵심 역할은 클래스 내부의 @Bean 어노테이션이 부여된 메서드가 담당한다. 따라서 @Configuration과 @Bean은 빈 설정을 구성하는 데 있어 상호 보완적이고 필수적인 관계에 있다.
@Configuration 클래스 내부에 작성된 @Bean 메서드는 스프링 IoC 컨테이너에 의해 관리될 객체를 생성하고 반환하는 팩토리 메서드로 동작한다. 컨테이너는 이 메서드를 호출하여 반환된 객체를 빈으로 등록하며, 메서드 이름이 기본적인 빈의 이름이 된다. 이때 @Configuration 어노테이션은 단순히 @Bean 메서드를 포함하는 클래스임을 표시하는 것을 넘어, 의존성 주입과 싱글톤 보장을 위한 특별한 처리를 가능하게 한다.
@Configuration이 적용되지 않은 일반 클래스(예: @Component가 적용된 클래스)에서도 @Bean 메서드를 선언할 수 있다. 그러나 이 경우에는 CGLIB 프록시에 의한 빈 간 메서드 호출이 가로채어지지 않아, 같은 클래스 내의 @Bean 메서드를 호출할 때마다 새로운 인스턴스가 생성될 수 있는 등의 제약이 따른다. 반면 @Configuration 클래스 내부에서는 한 @Bean 메서드가 다른 @Bean 메서드를 호출할 때, 스프링이 싱글톤 빈을 반환하도록 보장한다.
결론적으로, @Configuration은 @Bean 메서드들이 안전하게 상호 참조하며 싱글톤 스코프를 유지할 수 있는 컨텍스트를 제공하는 역할을 한다. 이 둘의 조합은 XML 기반 빈 설정 파일을 대체하는 현대적인 스프링 애플리케이션 구성의 표준 방식으로 자리 잡았다.
3.3. Configuration 클래스의 특징
3.3. Configuration 클래스의 특징
@Configuration 어노테이션이 적용된 클래스는 스프링 프레임워크의 자바 기반 설정 방식에서 빈 정의를 담는 중심적인 역할을 한다. 이 클래스는 일반적인 자바 클래스와 유사하지만, 스프링 IoC 컨테이너에 의해 특별하게 처리되어 애플리케이션의 객체 그래프를 구성하는 빈들을 선언적으로 정의할 수 있게 해준다.
이 클래스의 핵심 특징은 @Bean 어노테이션이 붙은 메서드가 호출될 때 싱글톤 범위의 빈을 보장하도록 CGLIB 라이브러리를 사용한 바이트코드 조작을 통해 프록시로 감싸진다는 점이다. 이 프록시 메커니즘 덕분에, 구성 클래스 내에서 하나의 빈 메서드를 여러 번 호출하더라도 스프링 컨테이너는 항상 동일한 인스턴스를 반환하여 불필요한 객체 생성을 방지하고 의존성 주입의 일관성을 유지한다.
또한, @Configuration 클래스는 그 자체가 컨테이너에 의해 관리되는 빈으로 등록된다. 따라서 다른 빈과 마찬가지로 의존성 주입을 받거나, 환경 변수를 주입받는 @Autowired나 @Value 같은 어노테이션을 사용할 수 있다. 이는 설정 값이나 다른 빈에 대한 참조를 클래스 내부에서 유연하게 활용할 수 있게 만든다.
이 클래스들은 컴포넌트 스캔의 대상이 될 수 있으며, @Import 어노테이션을 사용하거나 AnnotationConfigApplicationContext에 직접 등록함으로써 모듈화된 설정을 조합하는 데 용이하다. 이는 과거 XML 기반 설정 파일이 제공하던 모듈성과 유연성을 자바 코드로 대체하면서도 더욱 강력한 타입 안정성과 리팩토링 지원을 제공하는 장점으로 이어진다.
4. 사용 방법
4. 사용 방법
4.1. 기본 구성 클래스 작성
4.1. 기본 구성 클래스 작성
@Configuration 어노테이션을 사용한 기본 구성 클래스를 작성하는 방법은 직관적이다. 먼저, 구성 클래스로 사용할 자바 클래스를 생성하고 클래스 선언부에 @Configuration 어노테이션을 추가한다. 이 어노테이션은 스프링 프레임워크의 IoC 컨테이너에게 이 클래스가 하나 이상의 빈 정의를 포함하고 있음을 알리는 역할을 한다.
구성 클래스 내부에서는 빈을 정의하기 위해 @Bean 어노테이션을 메서드에 적용한다. 이 메서드는 빈의 인스턴스를 생성하고 구성하는 로직을 담으며, 반환 타입이 빈의 타입이 된다. 메서드 이름은 기본적으로 빈의 이름으로 사용된다. 예를 들어, DataSource나 JdbcTemplate과 같은 인프라스트럭처 빈을 구성하거나, 애플리케이션의 핵심 서비스 객체를 생성하여 반환할 수 있다.
기본적인 구성 클래스 예시는 다음과 같다.
```java
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyServiceImpl(myRepository());
}
@Bean
public MyRepository myRepository() {
return new MyRepositoryImpl();
}
}
```
이 예시에서 myService 빈은 myRepository 빈에 대한 의존성을 갖는다. @Configuration 클래스 내에서는 이러한 내부 메서드 호출이 의존성 주입을 위해 싱글톤으로 관리되는 기존 빈을 참조하도록 프록시된다.
이렇게 작성된 자바 기반 구성 클래스는 과거 주로 사용되던 XML 설정 파일을 대체할 수 있으며, 타입 안정성과 리팩토링의 용이성, 더 풍부한 표현력 등의 장점을 제공한다. 구성 클래스는 일반적으로 애플리케이션의 진입점인 AnnotationConfigApplicationContext에 등록되어 사용된다.
4.2. 의존성 주입 설정
4.2. 의존성 주입 설정
@Configuration 클래스 내에서 의존성 주입을 설정하는 핵심은 @Bean 메서드를 통해 빈을 정의하고, 이 메서드 간의 호출을 통해 빈들 사이의 의존 관계를 명시하는 것이다. 스프링 IoC 컨테이너는 @Configuration 클래스가 선언한 @Bean 메서드를 처리할 때, 기본적으로 CGLIB에 의해 생성된 프록시를 통해 메서드 호출을 가로챈다. 이를 통해 동일한 @Bean 메서드가 여러 번 호출되더라도 항상 동일한 싱글톤 빈 인스턴스를 반환하도록 보장한다. 따라서 한 빈이 다른 빈을 필요로 할 때, 해당 빈을 생성하는 @Bean 메서드를 직접 호출하는 것이 가장 일반적인 의존성 주입 설정 방법이다.
예를 들어, MyService 빈이 MyRepository 빈에 의존하는 경우, myService() @Bean 메서드 내에서 myRepository() 메서드를 호출하여 의존성을 주입할 수 있다. 이때 myRepository() 메서드는 새로운 인스턴스를 생성하는 것이 아니라, 스프링 컨테이너가 관리하는 기존의 싱글톤 MyRepository 빈을 반환한다. 이 방식은 Java 코드를 사용해 빈과 그 관계를 선언적으로 정의할 수 있어, XML 설정에 비해 타입 안전성과 리팩토링 용이성이 뛰어나다.
또 다른 주요 방법은 @Bean 메서드의 매개변수를 이용하는 것이다. 스프링 컨테이너는 @Bean 메서드를 호출할 때, 메서드 시그니처에 정의된 매개변수를 자동으로 컨테이너 내의 해당 타입의 빈으로 해석하여 주입한다. 이는 생성자 주입과 유사한 패턴으로, 의존 관계가 명확하게 드러난다는 장점이 있다. @Autowired 어노테이션을 @Configuration 클래스의 필드나 메서드에 사용하여 필요한 빈을 주입받은 후, @Bean 메서드 내에서 활용하는 방법도 가능하다.
의존성 주입 설정 시 주의할 점은, @Bean 메서드가 private, final 또는 static으로 선언되어서는 안 된다는 것이다. 이러한 메서드는 스프링의 CGLIB 프록시가 오버라이드할 수 없기 때문에, 싱글톤 보장 및 메서드 호출 가로채기 기능이 동작하지 않을 수 있다. 또한, 리터럴 값이나 간단한 객체를 주입해야 하는 경우에는 @Bean 메서드 내에서 직접 new 연산자로 생성하여 반환하면 된다.
4.3. 다중 구성 클래스 관리
4.3. 다중 구성 클래스 관리
하나의 애플리케이션에서는 여러 개의 구성 클래스를 사용하여 설정을 모듈화하는 것이 일반적이다. 이는 관심사를 분리하고, 특정 기능이나 모듈에 대한 설정을 독립적으로 관리하기 위함이다. 예를 들어, 데이터 소스 설정, 웹 MVC 설정, 보안 설정 등을 각각 별도의 @Configuration 클래스로 정의할 수 있다.
다중 구성 클래스를 관리하는 주요 방법은 @Import 어노테이션을 사용하는 것이다. 메인 구성 클래스에 @Import(다른구성클래스.class)를 선언하면, 해당 클래스에 정의된 @Bean 메서드들이 함께 등록된다. 또는 스프링 부트 애플리케이션의 경우, @SpringBootApplication 어노테이션이 붙은 메인 클래스가 컴포넌트 스캔을 수행하며, 이 과정에서 클래스패스 상의 모든 @Configuration 클래스를 자동으로 감지하고 등록한다.
구성 클래스 간의 의존 관계가 있을 경우, 한 구성 클래스 내에서 다른 구성 클래스에 정의된 빈을 메서드 호출이나 파라미터 주입을 통해 참조할 수 있다. 이때 스프링은 싱글톤 보장을 위해 CGLIB 프록시를 사용하므로, 동일한 빈을 여러 번 호출해도 매번 새로운 인스턴스가 생성되지 않는다. 또한, @Order 어노테이션이나 Ordered 인터페이스를 구현하여 구성 클래스의 처리 순서를 제어할 수 있으며, @DependsOn 어노테이션으로 특정 빈이 먼저 생성되도록 명시적 의존성을 지정할 수도 있다.
5. 고급 기능
5. 고급 기능
5.1. 프록시 모드 (CGLIB)
5.1. 프록시 모드 (CGLIB)
@Configuration 클래스는 기본적으로 CGLIB 라이브러리를 사용한 프록시로 감싸진다. 이 프록시는 @Bean 메서드에 대한 호출을 가로채어 스프링 프레임워크의 빈 싱글톤 생명주기를 보장하는 역할을 한다. 즉, 개발자가 @Bean 메서드를 직접 호출하더라도 프록시는 항상 컨테이너에 의해 관리되는 동일한 빈 인스턴스를 반환하도록 한다.
이 프록시 모드는 proxyBeanMethods 속성을 통해 제어할 수 있다. 기본값은 true로, CGLIB 프록시를 활성화하여 빈 메서드 간의 내부 호출에서도 싱글톤을 보장한다. 반면 @Configuration(proxyBeanMethods = false)로 설정하면 프록시 생성이 비활성화된다. 이 경우 @Bean 메서드는 일반 자바 메서드처럼 동작하며, 빈 메서드 간 호출 시 매번 새로운 인스턴스가 생성될 수 있다.
프록시 모드를 false로 설정하는 것은 성능 최적화 측면에서 유리할 수 있다. CGLIB 프록시 생성과 관련된 오버헤드가 없어지며, 클래스가 final이거나 private 메서드를 가져도 제약 없이 사용할 수 있다. 이 방식은 빈들 간의 의존성이 명시적으로 주입되는 구성 클래스나, 리터럴 값을 반환하는 단순한 설정에 적합하다.
따라서 proxyBeanMethods 설정은 애플리케이션의 구성 방식과 성능 요구사항에 따라 선택적으로 적용해야 한다. 빈 메서드 간의 호출이 빈번하고 싱글톤 보장이 중요한 복잡한 설정에서는 기본값을 유지하는 것이 안전하며, 그렇지 않은 경우에는 false로 설정하여 경량화를 고려할 수 있다.
5.2. 조건부 빈 등록 (@Conditional)
5.2. 조건부 빈 등록 (@Conditional)
@Conditional 어노테이션은 스프링 프레임워크에서 특정 조건이 충족될 때만 빈 정의나 @Configuration 클래스 자체가 활성화되도록 하는 메커니즘이다. 이 기능은 개발 환경, 운영 환경, 특정 프로파일 또는 시스템 속성의 존재 여부 등에 따라 애플리케이션 구성을 동적으로 변경해야 할 때 매우 유용하다. 조건부 빈 등록을 통해 불필요한 빈이 스프링 IoC 컨테이너에 등록되는 것을 방지하고, 상황에 맞는 최적의 의존성 주입 구성을 가능하게 한다.
@Conditional 어노테이션은 Condition 인터페이스를 구현한 하나 이상의 클래스를 인자로 받는다. 이 Condition 구현체는 matches 메서드를 오버라이드하여 복잡한 조건 로직을 정의할 수 있다. 스프링은 빈을 등록하기 전에 이 조건을 평가하고, 조건이 true를 반환할 때만 해당 빈 정의를 처리한다. 이 평가는 컨테이너의 빈 팩토리 후처리기 단계에서 이루어진다.
스프링은 일반적으로 사용되는 여러 조건 어노테이션을 미리 제공한다. 대표적으로 @ConditionalOnProperty는 특정 환경 변수나 애플리케이션 프로퍼티의 값에 따라, @ConditionalOnClass는 특정 클래스가 클래스패스에 존재할 때에 따라, @ConditionalOnMissingBean은 특정 타입의 빈이 이미 컨테이너에 등록되어 있지 않을 때에 따라 빈을 등록하도록 한다. 이러한 어노테이션들은 주로 스프링 부트의 자동 구성(Auto-Configuration) 모듈에서 광범위하게 사용된다.
조건부 빈 등록은 모듈화와 유연성을 크게 향상시킨다. 예를 들어, 개발 환경에서는 H2 데이터베이스용 데이터 소스 빈을, 운영 환경에서는 MySQL 또는 PostgreSQL용 데이터 소스 빈을 조건에 따라 등록할 수 있다. 또한, 특정 기능 플래그가 활성화되었을 때만 고급 서비스 빈을 등록하는 식으로 기능 토글을 구현하는 데에도 활용된다.
5.3. 프로파일 기반 구성 (@Profile)
5.3. 프로파일 기반 구성 (@Profile)
프로파일 기반 구성은 스프링 프레임워크에서 특정 환경이나 조건에 따라 다른 빈 설정을 적용할 수 있게 해주는 기능이다. @Profile 어노테이션을 사용하여 구현하며, 개발, 테스트, 운영 환경 등 서로 다른 배포 단계나 목적에 맞춘 구성 클래스나 빈 메서드를 정의할 수 있다. 이는 단일 애플리케이션 코드베이스에서 환경별 설정을 깔끔하게 분리하는 데 핵심적인 역할을 한다.
@Profile 어노테이션은 @Configuration 클래스 자체 또는 @Bean 메서드 수준에 적용할 수 있다. 예를 들어, 개발 환경에서는 H2 데이터베이스와 같은 인메모리 데이터베이스를 사용하고, 운영 환경에서는 MySQL이나 PostgreSQL과 같은 실제 데이터베이스에 연결하도록 구성할 수 있다. 활성화할 프로파일은 JVM 시스템 속성, 환경 변수, 또는 애플리케이션 컨텍스트 초기화 과정에서 지정할 수 있다.
이 기능을 통해 환경에 따라 달라지는 데이터소스, 외부 API 엔드포인트, 로깅 레벨, 캐시 설정 등을 유연하게 관리할 수 있다. 또한, 통합 테스트 시 특정 프로파일을 활성화하여 실제 인프라가 아닌 모의 객체(Mock Object)를 사용하도록 구성하는 등 테스트 전략에도 활용된다.
6. 주요 이슈 및 모범 사례
6. 주요 이슈 및 모범 사례
6.1. 싱글톤 보장과 주의사항
6.1. 싱글톤 보장과 주의사항
@Configuration 클래스 내부에서 @Bean 메서드를 통해 정의된 빈은 기본적으로 싱글톤 범위를 가집니다. 이는 스프링 IoC 컨테이너가 해당 빈의 인스턴스를 하나만 생성하여 관리하며, 어플리케이션 전반에 걸쳐 동일한 인스턴스를 재사용함을 의미합니다. 이러한 싱글톤 보장은 @Configuration 클래스가 CGLIB 라이브러리에 의해 프록시되기 때문에 가능합니다. 프록시는 @Bean 메서드에 대한 호출을 가로채서, 이미 컨테이너에 등록된 빈이 있다면 새 인스턴스를 생성하지 않고 기존 인스턴스를 반환하는 방식으로 싱글톤을 유지합니다.
주의해야 할 주요 사항은 @Configuration 어노테이션 없이 @Component나 일반 클래스에 @Bean 메서드를 사용하는 경우입니다. 이 경우 CGLIB 프록시가 적용되지 않아 싱글톤이 보장되지 않을 수 있습니다. 예를 들어, 하나의 @Bean 메서드가 내부에서 다른 @Bean 메서드를 호출할 때, 매번 새로운 인스턴스가 생성될 수 있습니다. 이는 의도하지 않은 메모리 사용 증가와 의존성 주입의 일관성을 해칠 수 있습니다.
또 다른 주의사항은 @Configuration 클래스 내부에서 정적 메서드로 @Bean을 선언하는 것입니다. 정적 @Bean 메서드는 CGLIB 프록시의 대상이 되지 않으며, 이는 해당 빈이 의존성 주입이나 다른 빈에 대한 메서드 호출을 통해 주입받을 수 없음을 의미합니다. 정적 @Bean 메서드는 주로 라이프사이클 콜백이나 성능 최적화를 위해 특수한 경우에 제한적으로 사용됩니다.
마지막으로, 리소스 정리와 관련된 라이프사이클 관리에 유의해야 합니다. 싱글톤 빈은 어플리케이션 컨텍스트가 종료될 때까지 메모리에 상주하므로, 데이터베이스 연결이나 파일 핸들과 같은 제한된 시스템 리소스를 많이 사용하는 빈을 정의할 때는 신중해야 합니다. 필요시 @PreDestroy 어노테이션 등을 사용해 명시적인 정리 로직을 구현하는 것이 좋습니다.
6.2. 성능 고려사항
6.2. 성능 고려사항
@Configuration 클래스의 성능을 고려할 때는 주로 스프링 프레임워크가 구성 클래스를 처리하는 방식과 관련된 요소들을 검토해야 한다. 핵심은 CGLIB 프록시를 사용하는 프록시 모드와 이를 사용하지 않는 라이트 모드 간의 선택이다. 기본적으로 @Configuration 클래스는 CGLIB에 의해 프록시되어, @Bean 메서드 간의 내부 호출이 싱글톤 빈을 보장하도록 인터셉트된다. 이 프록시 생성 과정은 애플리케이션 시작 시 약간의 오버헤드를 발생시킬 수 있다.
성능 최적화를 위해, 빈 정의 간의 메서드 호출이 필요 없는 단순한 구성 클래스의 경우 proxyBeanMethods = false 속성을 사용할 수 있다. 이 라이트 모드는 프록시 생성을 생략하여 시작 시간을 단축하고 메모리 사용량을 줄인다. 그러나 이 모드에서는 @Bean 메서드를 다른 @Bean 메서드에서 직접 호출할 때 새로운 인스턴스가 반환될 수 있어 싱글톤 보장에 주의해야 한다. 따라서 구성 클래스의 설계와 빈 간의 의존 관계를 정확히 이해한 상태에서 선택하는 것이 중요하다.
또 다른 성능 고려사항은 구성 클래스의 스캔 범위와 수이다. 너무 많은 @Configuration 클래스를 등록하거나 불필요하게 넓은 컴포넌트 스캔 경로를 설정하면 애플리케이션 컨텍스트 초기화 시간이 길어질 수 있다. @Profile이나 @Conditional과 같은 조건부 어노테이션을 활용하여 특정 환경에서만 필요한 빈 설정을 로드하도록 구성하면, 불필요한 빈 정의 처리를 방지하여 성능에 긍정적인 영향을 줄 수 있다.
6.3. 테스트 구성
6.3. 테스트 구성
@Configuration 클래스를 테스트할 때는 스프링의 테스트 지원 프레임워크를 활용한다. 주로 @SpringBootTest나 @ContextConfiguration 어노테이션을 사용하여 테스트 실행 시 특정 구성 클래스를 로드할 수 있다. 이를 통해 실제 스프링 IoC 컨테이너가 구성 클래스에 정의된 빈을 올바르게 생성하고 의존성 주입을 수행하는지 검증할 수 있다. 또한, @TestConfiguration 어노테이션을 사용하면 테스트 전용의 추가 빈 정의나 기존 빈을 대체하는 설정을 쉽게 제공할 수 있어, 통합 테스트와 단위 테스트 모두에 유용하게 적용된다.
테스트 시에는 특정 빈이 컨텍스트에 존재하는지 확인하거나, 그 빈의 속성 및 의존 관계가 예상대로 주입되었는지 검증하는 것이 일반적이다. @Autowired를 통해 테스트 대상 빈을 주입받고, AssertJ나 JUnit의 Assertion을 이용해 상태를 검증한다. 특히 @Configuration 클래스 내부에서 @Bean 메서드가 호출될 때 CGLIB 프록시에 의해 싱글톤이 보장되는 동작 방식을 테스트에서도 확인할 수 있어야 한다.
테스트의 효율성을 높이기 위해, 특정 프로파일이 활성화되었을 때만 로드되는 구성(@Profile)이나 조건부 빈 등록(@Conditional)이 예상대로 작동하는지도 검증해야 한다. 이를 위해 @ActiveProfiles 어노테이션으로 테스트 프로파일을 지정하거나, ApplicationContextRunner와 같은 도구를 사용해 조건부 구성의 동작을 유연하게 테스트할 수 있다. 이러한 접근법은 복잡한 빈 구성 로직의 신뢰성을 보장하는 데 핵심적이다.
