본문 바로가기

SpringFramework Core - I. IoC 컨테이너/12. 자바 기반의 컨테이너 설정

12.1. 기본 개념들 : @Bean : @Bean과 @Configuration

원문: https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-java-basic-concepts

 

 

스프링의 새로운 자바 설정 지원에 있어서 가장 중심적인 것은 @Configuration 어노테이션이 붙은 클래스들과 @Bean 어노테이션이 붙은 메소드들이다.

 

@Bean 어노테이션은 메소드의 인스턴스화, 설정, 새로운 객체의 초기화를 명시하기 위해서 사용된다. 스프링의 <beans/> XML 설정과 유사하게, @Bean 어노테이션은 <bean/> 요소와 같은 역할을 수행한다. @Bean 어노테이션이 붙은 메소드를 스프링 @Component와 함께 사용할 수 있다. 그러나 @Configuration bean들이 대부분 사용된다. 

 

클래스에 @Configuration을 붙이는 것은 해당 클래스의 목적이 bean 정의의 원천이라는 것을 가리키게 된다. 게다가 @Configuration 클래스들은 같은 클래스 내의 @Bean 메소드들을 호출함으로써 내부 bean 의존을 할 수 있다. 가능한 한 간단한 @Configuration 클래스는 다음과 같다.

@Configuration
public class AppConfig {

    @Bean
    public MyService myService() {
        return new MyServiceImpl();
    }
}

위 AppConfig 클래스는 다음 스프링 <beans/> XML과 같다.

<beans>
    <bean id="myService" class="com.acme.services.MyServiceImpl" />
</beans>
                                    완전한 @Configuration vs "가벼운" @Bean 모드

@Bean 메소드들이 @Configuration이 붙지 않은 클래스에서 선언되면, "가벼운" 모드로 실행된다고 말한다. @Component 안이나 POJO에서 선언된 Bean의 메소드들은 "가볍"다고 여겨진다. 이때, 클래스와 @Bean 메소드를 포함한다는 클래스의 목적이 달라지면서 추가적인 기능들을 얻게 된다. 예를 들어, 서비스 컴포넌트들은 @Bean 메소드를 추가함으로써 컨테이너에게 관리 view들을 제공하게 된다. 각각의 상황에서 @Bean 메소드들은 일반적인 목적을 갖는 팩토리 메소드 메커니즘이다.

완전한 @Configuration과 달리, 가벼운 @Bean 메소드는 내부 bean 의존을 선언할 수 없다. 대신, 해당 메소드들은 컴포넌트의 내부 상태를 기반으로 작동하며, 선택적으로는 그들이 선언한 매개변수들을 기반으로 작동한다. 그러므로 @Bean 메소드는 다른 @Bean 메소드를 호출해서는 안 된다. 각 메소드는 말 그대로 특정 bean 참조를 위한 팩토리 메소드이며 런타임 시에 특별한 의미를 갖게 되는 일은 없다. 긍정적인 효과라고 한다면, 런타임 시에 CGLIB 서브클래싱이 적용될 필요가 없다는 점이 있다. 그래서 클래스 설계의 관점에서 한계를 갖지 않게 된다(즉, @Bean 메소드를 포함하는 클래스는 final일 것이다).

일반적인 경우에, @Bean 메소드들은 @Configuration 클래스 안에서 선언된다. 이는 "완전한" 모드가 항상 사용가능하도록 보장하며, 따라서 메소드 간 상호참조들이 컨테이너의 라이프사이클 관리를 통해 리다이렉트될 수 있도록 보장한다. 이는 일반적인 자바 호출을 통해 우연히 같은 @Bean 메소드가 호출되는 것을 예방한다. 이는 "가벼운" 모드에서 작동될 때 파악하기 어려운 미묘한 버그들을 줄이는 데 도움을 준다.

@Bean과 @Configuration 어노테이션들은 다음 장에서 살펴볼 것이다. 그러나 먼저, 자바 기반의 설정을 사용하여 스프링 컨테이너를 생성하는 다양한 방법을 다룰 것이다.