Loading...
Spring Framework Reference Documentation 7.0.2의 Customizing the Nature of a Bean의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
Spring Framework는 bean의 특성을 사용자 정의할 수 있는 여러 인터페이스를 제공합니다. 이 섹션에서는 이를 다음과 같이 그룹화합니다:
컨테이너의 bean 라이프사이클 관리와 상호 작용하기 위해 Spring InitializingBean 및 DisposableBean 인터페이스를 구현할 수 있습니다. 컨테이너는 전자에 대해서는 afterPropertiesSet(), 후자에 대해서는 destroy()를 호출하여 bean이 bean의 초기화 및 소멸 시점에 특정 동작을 수행하도록 합니다.
JSR-250
@PostConstruct및@PreDestroy어노테이션은 일반적으로 최신 Spring 애플리케이션에서 라이프사이클 콜백을 받기 위한 모범 사례로 간주됩니다.<br>이러한 어노테이션을 사용하면 bean이 Spring-specific 인터페이스에 결합되지 않습니다.<br>자세한 내용은 Using@PostConstructand@PreDestroy를 참조하십시오.<br>JSR-250 어노테이션을 사용하고 싶지 않지만 여전히 결합을 제거하고자 한다면,<br>init-method및destroy-methodbean 정의 메타데이터를 고려하십시오.
내부적으로 Spring Framework는 BeanPostProcessor 구현을 사용하여 찾을 수 있는 콜백 인터페이스를 처리하고 적절한 메서드를 호출합니다. Spring이 기본적으로 제공하지 않는 custom 기능이나 다른 라이프사이클 동작이 필요한 경우 직접 BeanPostProcessor를 구현할 수 있습니다. 자세한 내용은
Container Extension Points를 참조하십시오.
초기화 및 소멸 콜백에 추가로, Spring이 관리하는 객체는 Lifecycle 인터페이스를 구현하여 해당 객체가 컨테이너 자체의 라이프사이클에 의해 구동되는 startup 및 shutdown 프로세스에 참여할 수 있습니다.
라이프사이클 콜백 인터페이스는 이 섹션에서 설명합니다.
org.springframework.beans.factory.InitializingBean 인터페이스는 bean이 컨테이너가 bean에 필요한 모든 프로퍼티를 설정한 후 초기화 작업을 수행할 수 있도록 합니다. InitializingBean 인터페이스는 하나의 메서드를 지정합니다:
1void afterPropertiesSet() throws Exception;
InitializingBean 인터페이스는 코드를 불필요하게 Spring에 결합시키므로 사용하지 않을 것을 권장합니다. 대신 @PostConstruct 어노테이션을 사용하거나 POJO 초기화 메서드를 지정할 것을 제안합니다. XML 기반 설정 메타데이터의 경우, void 반환형의 무인자 시그니처를 가지는 메서드 이름을 지정하기 위해 init-method 애트리뷰트를 사용할 수 있습니다. Java 설정에서는 @Bean의 initMethod 애트리뷰트를 사용할 수 있습니다. Receiving Lifecycle Callbacks를 참조하십시오. 다음 예제를 고려해 보십시오:
1<bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/>
1public class ExampleBean { 2 3 public void init() { 4 // do some initialization work 5 } 6}
1class ExampleBean { 2 3 fun init() { 4 // do some initialization work 5 } 6}
앞의 예제는 (두 개의 listing으로 구성된) 다음 예제와 거의 동일한 효과를 가집니다:
1<bean id="exampleInitBean" class="examples.AnotherExampleBean"/>
1public class AnotherExampleBean implements InitializingBean { 2 3 @Override 4 public void afterPropertiesSet() { 5 // do some initialization work 6 } 7}
1class AnotherExampleBean : InitializingBean { 2 3 override fun afterPropertiesSet() { 4 // do some initialization work 5 } 6}
그러나 앞의 두 예제 중 첫 번째 예제는 코드를 Spring에 결합시키지 않습니다.
@PostConstruct및 일반적인 초기화 메서드는 컨테이너의 싱글톤 생성 락 내에서 실행된다는 점에 유의하십시오.<br>Bean 인스턴스는@PostConstruct메서드에서 반환된 후에만 완전히 초기화되고 다른 곳에 공개할 준비가 된 것으로 간주됩니다.<br>이러한 개별 초기화 메서드는 구성 상태를 검증하고 주어진 구성에 기반하여 일부 데이터 구조를 준비하는 데만 사용되어야 하며,<br>외부 bean 접근과의 추가 활동에는 사용되지 않아야 합니다.<br>그렇지 않으면 초기화 데드락의 위험이 있습니다.<br>비용이 많이 드는 post-initialization activity(예: 비동기 데이터베이스 준비 단계)를 트리거해야 하는 시나리오의 경우,<br>bean은SmartInitializingSingleton.afterSingletonsInstantiated()를 구현하거나 context refresh 이벤트에 의존해야 합니다:<br>ApplicationListener<ContextRefreshedEvent>를 구현하거나 해당 어노테이션인@EventListener(ContextRefreshedEvent.class)를 선언하십시오.<br>이러한 variant는 모든 일반 싱글톤 초기화 이후, 따라서 싱글톤 생성 락 외부에 수행됩니다.<br>또는(Smart)Lifecycle인터페이스를 구현하고 컨테이너의 전체 라이프사이클 관리와 통합할 수 있습니다.<br>여기에는 자동 시작 메커니즘, pre-destroy stop 단계, 잠재적인 stop/restart 콜백(아래 참조)이 포함됩니다.
org.springframework.beans.factory.DisposableBean 인터페이스를 구현하면 bean은 자신을 포함하는 컨테이너가 소멸될 때 콜백을 받을 수 있습니다. DisposableBean 인터페이스는 하나의 메서드를 지정합니다:
1void destroy() throws Exception;
DisposableBean 콜백 인터페이스는 코드를 불필요하게 Spring에 결합시키므로 사용하지 않을 것을 권장합니다. 대신 @PreDestroy 어노테이션을 사용하거나 bean 정의에서 지원하는 일반적인 메서드를 지정할 것을 제안합니다. XML 기반 설정 메타데이터에서는 <bean/>에 destroy-method 애트리뷰트를 사용할 수 있습니다. Java 설정에서는 @Bean의 destroyMethod 애트리뷰트를 사용할 수 있습니다. Receiving Lifecycle Callbacks를 참조하십시오. 다음 정의를 고려해 보십시오:
1<bean id="exampleDestructionBean" class="examples.ExampleBean" destroy-method="cleanup"/>
1public class ExampleBean { 2 3 public void cleanup() { 4 // do some destruction work (like releasing pooled connections) 5 } 6}
1class ExampleBean { 2 3 fun cleanup() { 4 // do some destruction work (like releasing pooled connections) 5 } 6}
앞의 정의는 다음 정의와 거의 동일한 효과를 가집니다:
1<bean id="exampleDestructionBean" class="examples.AnotherExampleBean"/>
1public class AnotherExampleBean implements DisposableBean { 2 3 @Override 4 public void destroy() { 5 // do some destruction work (like releasing pooled connections) 6 } 7}
1class AnotherExampleBean : DisposableBean { 2 3 override fun destroy() { 4 // do some destruction work (like releasing pooled connections) 5 } 6}
그러나 앞의 두 정의 중 첫 번째 정의는 코드를 Spring에 결합시키지 않습니다.
Spring은 또한 public close 또는 shutdown 메서드를 감지하여 destroy 메서드를 추론하는 것을 지원합니다. 이는 Java 설정 클래스에서 @Bean 메서드에 대한 기본 동작이며, java.lang.AutoCloseable 또는 java.io.Closeable 구현을 자동으로 매칭하여 소멸 로직을 Spring에 결합시키지 않습니다.
XML에서 destroy 메서드 추론을 위해
<bean>요소의destroy-method애트리뷰트에 특수 값(inferred)를 할당할 수 있습니다.<br>이 값은 Spring에게 특정 bean 정의에 대해 bean 클래스에서 publicclose또는shutdown메서드를 자동으로 감지하도록 지시합니다.<br>또한<beans>요소의default-destroy-method애트리뷰트에 이 특수 값(inferred)를 설정하여<br>이 동작을 전체 bean 정의 집합에 적용할 수 있습니다(see<br>Default Initialization and Destroy Methods).
확장된 shutdown phase의 경우,
Lifecycle인터페이스를 구현하여 어떤 싱글톤 bean의 destroy 메서드가 호출되기 전에<br>조기 stop signal을 받을 수 있습니다.<br>또한SmartLifecycle을 구현하여 컨테이너가 destroy 메서드로 넘어가기 전에<br>모든 stop processing이 완료될 때까지 기다리는 time-bound stop 단계를 가질 수 있습니다.
Spring-specific InitializingBean 및 DisposableBean 콜백 인터페이스를 사용하지 않는 초기화 및 destroy 메서드 콜백을 작성할 때 일반적으로 init(), initialize(), dispose() 등의 이름을 가진 메서드를 작성합니다. 이상적으로 이러한 라이프사이클 콜백 메서드의 이름은 프로젝트 전반에 걸쳐 표준화되어 모든 개발자가 동일한 메서드 이름을 사용하고 일관성을 보장해야 합니다.
Spring 컨테이너가 모든 bean에서 명명된 초기화 및 destroy 콜백 메서드 이름을 “찾도록” 구성할 수 있습니다. 이는 애플리케이션 개발자인 여러분이 애플리케이션 클래스를 작성하고 init()이라는 초기화 콜백을 사용할 수 있음을 의미하며, 각 bean 정의에 init-method="init" 애트리뷰트를 구성할 필요가 없습니다. Spring IoC 컨테이너는 bean이 생성될 때(및 앞서 설명한 표준 라이프사이클 콜백 계약에 따라) 해당 메서드를 호출합니다.
이 기능은 또한 초기화 및 destroy 메서드 콜백에 대한 일관된 명명 규칙을 강제합니다.
초기화 콜백 메서드가 init()이고 destroy 콜백 메서드가 destroy()라고 가정해 보겠습니다. 그러면 클래스는 다음 예제의 클래스와 유사합니다:
1public class DefaultBlogService implements BlogService { 2 3 private BlogDao blogDao; 4 5 public void setBlogDao(BlogDao blogDao) { 6 this.blogDao = blogDao; 7 } 8 9 // this is (unsurprisingly) the initialization callback method 10 public void init() { 11 if (this.blogDao == null) { 12 throw new IllegalStateException("The [blogDao] property must be set."); 13 } 14 } 15}
1class DefaultBlogService : BlogService { 2 3 private var blogDao: BlogDao? = null 4 5 // this is (unsurprisingly) the initialization callback method 6 fun init() { 7 if (blogDao == null) { 8 throw IllegalStateException("The [blogDao] property must be set.") 9 } 10 } 11}
그런 다음 다음과 유사한 bean에서 해당 클래스를 사용할 수 있습니다:
1<beans default-init-method="init"> 2 3 <bean id="blogService" class="com.something.DefaultBlogService"> 4 <property name="blogDao" ref="blogDao" /> 5 </bean> 6 7</beans>
최상위 <beans/> 요소 애트리뷰트에 default-init-method 애트리뷰트가 존재하면 Spring IoC 컨테이너는 bean 클래스에서 init이라는 메서드를 초기화 메서드 콜백으로 인식합니다. Bean이 생성 및 조립될 때, bean 클래스에 해당 메서드가 있으면 적절한 시점에 호출됩니다.
유사하게(즉, XML에서) 최상위 <beans/> 요소의 default-destroy-method 애트리뷰트를 사용하여 destroy 메서드 콜백을 구성할 수 있습니다.
기존 bean 클래스에 convention과 다르게 명명된 콜백 메서드가 이미 있는 경우, <bean/> 자체의 init-method 및 destroy-method 애트리뷰트를 사용하여(즉, XML에서) 메서드 이름을 지정함으로써 default를 override할 수 있습니다.
Spring 컨테이너는 구성된 초기화 콜백이 bean에 모든 의존성이 제공된 직후 호출됨을 보장합니다. 따라서 초기화 콜백은 raw bean reference에 대해 호출되며, 이는 AOP 인터셉터 등이 아직 bean에 적용되지 않았음을 의미합니다. Target bean은 먼저 완전히 생성된 다음 인터셉터 체인이 있는 AOP 프록시(예를 들어)가 적용됩니다. Target bean과 프록시가 별도로 정의된 경우, 코드는 프록시를 우회하여 raw target bean과 상호 작용할 수도 있습니다. 따라서 인터셉터를 init 메서드에 적용하는 것은 일관성이 없는데, 이는 그렇게 하면 target bean의 라이프사이클이 해당 프록시 또는 인터셉터에 결합되고 코드가 raw target bean과 직접 상호 작용할 때 이상한 시맨틱을 남기기 때문입니다.
Spring 2.5부터 bean 라이프사이클 동작을 제어하기 위해 세 가지 옵션이 있습니다:
InitializingBean 및
DisposableBean 콜백 인터페이스init() 및 destroy() 메서드@PostConstruct and @PreDestroy 어노테이션Bean에 대해 여러 라이프사이클 메커니즘이 구성되고 각 메커니즘이 서로 다른 메서드 이름으로 구성된 경우,<br>구성된 각 메서드는 이 note 이후에 나열된 순서대로 실행됩니다.<br>그러나 동일한 메서드 이름(예: 초기화 메서드에 대한
init())이<br>이러한 라이프사이클 메커니즘 중 둘 이상에 대해 구성된 경우,<br>해당 메서드는 앞의 섹션에서 설명한 대로 한 번만 실행됩니다.
동일한 bean에 대해 서로 다른 초기화 메서드와 함께 여러 라이프사이클 메커니즘이 구성된 경우 다음과 같이 호출됩니다:
@PostConstruct가 어노테이션된 메서드InitializingBean 콜백 인터페이스에 의해 정의된 afterPropertiesSet()init() 메서드Destroy 메서드는 동일한 순서로 호출됩니다:
@PreDestroy가 어노테이션된 메서드DisposableBean 콜백 인터페이스에 의해 정의된 destroy()destroy() 메서드Lifecycle 인터페이스는 자체 라이프사이클 요구 사항(예: 일부 백그라운드 프로세스를 시작 및 중지하는 등)이 있는 모든 객체에 대한 필수 메서드를 정의합니다:
1public interface Lifecycle { 2 3 void start(); 4 5 void stop(); 6 7 boolean isRunning(); 8}
Spring이 관리하는 모든 객체는 Lifecycle 인터페이스를 구현할 수 있습니다. 그런 다음 ApplicationContext 자체가 start 및 stop signal(예: 런타임에서 stop/restart 시나리오)을 수신하면 해당 context 내에 정의된 모든 Lifecycle 구현에 이러한 호출을 cascade합니다. 이는 다음 listing에 표시된 대로 LifecycleProcessor에 위임하여 수행합니다:
1public interface LifecycleProcessor extends Lifecycle { 2 3 void onRefresh(); 4 5 void onClose(); 6}
LifecycleProcessor 자체가 Lifecycle 인터페이스의 확장이라는 점에 주목하십시오. 또한 context가 refresh 및 close될 때 반응하기 위한 두 개의 메서드를 추가합니다.
일반적인
org.springframework.context.Lifecycle인터페이스는 explicit start 및 stop notification에 대한 단순 계약이며<br>context refresh 시점에 auto-startup을 의미하지 않는다는 점에 유의하십시오.<br>Auto-startup에 대한 세밀한 제어와 특정 bean의 graceful stopping(시작 및 stop phase 포함)을 위해서는<br>대신 확장된org.springframework.context.SmartLifecycle인터페이스를 구현하는 것을 고려하십시오.<br>또한 stop notification이 destruction보다 먼저 온다는 보장은 없습니다.<br>일반적인 shutdown에서는 모든Lifecyclebean이 일반적인 destruction 콜백이 전파되기 전에 먼저 stop notification을 받습니다.<br>그러나 context lifetime 동안의 hot refresh 또는 중단된 refresh 시도에서는 destroy 메서드만 호출됩니다.
Startup 및 shutdown 호출의 순서는 중요할 수 있습니다. 두 객체 사이에 “depends-on” 관계가 있는 경우, 의존하는 쪽은 dependency 이후에 시작되고 dependency 이전에 중지됩니다. 그러나 때때로 직접적인 dependency는 알 수 없습니다. 특정 type의 객체가 다른 type의 객체보다 먼저 시작되어야 한다는 것만 알 수 있습니다. 이러한 경우 SmartLifecycle 인터페이스는 super-interface인 Phased에 정의된 getPhase() 메서드라는 또 다른 옵션을 정의합니다. 다음 listing은 Phased 인터페이스의 정의를 보여줍니다:
1public interface Phased { 2 3 int getPhase(); 4}
다음 listing은 SmartLifecycle 인터페이스의 정의를 보여줍니다:
1public interface SmartLifecycle extends Lifecycle, Phased { 2 3 boolean isAutoStartup(); 4 5 void stop(Runnable callback); 6}
시작 시, phase가 가장 낮은 객체가 먼저 시작됩니다. 중지 시에는 반대 순서가 따릅니다. 따라서 SmartLifecycle을 구현하고 getPhase() 메서드가 Integer.MIN_VALUE를 반환하는 객체는 가장 먼저 시작되고 가장 나중에 중지됩니다. 반대 극단에서 Integer.MAX_VALUE의 phase 값은 해당 객체가 마지막에 시작되고 처음에 중지되어야 함을 나타냅니다(아마도 다른 프로세스가 실행 중이어야 하기 때문입니다). Phase 값을 고려할 때, SmartLifecycle을 구현하지 않는 “일반적인” Lifecycle 객체의 default phase는 0이라는 점도 중요합니다. 따라서 음수 phase 값은 객체가 이러한 표준 컴포넌트보다 먼저 시작(그리고 나중에 중지)되어야 함을 나타냅니다. 양수 phase 값의 경우 그 반대입니다.
SmartLifecycle에 의해 정의된 stop 메서드는 콜백을 인수로 받습니다. 모든 구현은 해당 구현의 shutdown 프로세스가 완료된 후 해당 콜백의 run() 메서드를 호출해야 합니다. 이는 필요할 경우 비동기 shutdown을 가능하게 하는데, LifecycleProcessor 인터페이스의 default 구현인 DefaultLifecycleProcessor는 각 phase 내의 객체 그룹이 해당 콜백을 호출할 때까지 timeout 값만큼 대기하기 때문입니다. Phase당 default timeout은 30초입니다. Context 내에 lifecycleProcessor라는 이름의 bean을 정의하여 default 라이프사이클 프로세서 인스턴스를 override할 수 있습니다. Timeout만 수정하려는 경우, 다음을 정의하는 것으로 충분합니다:
1<bean id="lifecycleProcessor" class="org.springframework.context.support.DefaultLifecycleProcessor"> 2 <!-- timeout value in milliseconds --> 3 <property name="timeoutPerShutdownPhase" value="10000"/> 4</bean>
앞서 언급했듯이, LifecycleProcessor 인터페이스는 context의 refresh 및 close에 대한 콜백 메서드도 정의합니다. 후자는 context가 close될 때 stop()이 명시적으로 호출된 것처럼 shutdown 프로세스를 구동합니다. 반면 'refresh' 콜백은 SmartLifecycle bean의 또 다른 기능을 가능하게 합니다. Context가 refresh될 때(모든 객체가 인스턴스화 및 초기화된 후), 해당 콜백이 호출됩니다. 그 시점에서 default 라이프사이클 프로세서는 각 SmartLifecycle 객체의 isAutoStartup() 메서드가 반환하는 boolean 값을 확인합니다. true이면 해당 객체는 context 또는 자신의 start() 메서드가 명시적으로 호출되기를 기다리는 대신 그 시점에 시작됩니다(표준 context 구현의 경우 context refresh와 달리 context start는 자동으로 발생하지 않습니다). phase 값과 모든 “depends-on” 관계는 앞서 설명한 대로 startup 순서를 결정합니다.
이 섹션은 non-web 애플리케이션에만 적용됩니다. Spring의 web-based<br>
ApplicationContext구현에는 관련 web 애플리케이션이 shutdown될 때 Spring IoC 컨테이너를<br>gracefully shut down하는 코드가 이미 포함되어 있습니다.
Spring의 IoC 컨테이너를 non-web 애플리케이션 환경(예: rich client desktop 환경)에서 사용하는 경우, JVM에 shutdown hook을 등록하십시오. 이렇게 하면 graceful shutdown이 보장되고 싱글톤 bean의 관련 destroy 메서드가 호출되어 모든 리소스가 해제됩니다. 이러한 destroy 콜백을 올바르게 구성하고 구현해야 합니다.
Shutdown hook을 등록하려면, 다음 예제에서 보는 것처럼 ConfigurableApplicationContext 인터페이스에 선언된 registerShutdownHook() 메서드를 호출하십시오:
1import org.springframework.context.ConfigurableApplicationContext; 2import org.springframework.context.support.ClassPathXmlApplicationContext; 3 4public final class Boot { 5 6 public static void main(final String[] args) throws Exception { 7 ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); 8 9 // add a shutdown hook for the above context... 10 ctx.registerShutdownHook(); 11 12 // app runs here... 13 14 // main method exits, hook is called prior to the app shutting down... 15 } 16}
1import org.springframework.context.support.ClassPathXmlApplicationContext 2 3fun main() { 4 val ctx = ClassPathXmlApplicationContext("beans.xml") 5 6 // add a shutdown hook for the above context... 7 ctx.registerShutdownHook() 8 9 // app runs here... 10 11 // main method exits, hook is called prior to the app shutting down... 12}
Spring core 컨테이너는 싱글톤 락을 통해 접근을 보호하고 다른 스레드에서의 visibility를 보장하여 생성된 싱글톤 인스턴스를 thread-safe한 방식으로 publish합니다.
그 결과, 애플리케이션이 제공하는 bean 클래스는 초기화 상태의 visibility에 대해 신경 쓸 필요가 없습니다. 정규 설정 필드는 초기화 phase 동안에만 변경되는 한 volatile로 표시될 필요가 없으며, 초기 phase 동안 변경 가능한 setter 기반 설정 상태에도 final과 유사한 visibility 보장을 제공합니다. 이러한 필드가 bean 생성 phase 및 이후의 초기 publish 이후에 변경되는 경우, 접근될 때마다 volatile로 선언되거나 공통 락에 의해 보호되어야 합니다.
예를 들어 컨트롤러 인스턴스나 리포지토리 인스턴스에 대한 싱글톤 bean 인스턴스의 이러한 설정 상태에 대한 동시 접근은 컨테이너 측의 안전한 초기 publish 이후 완전히 thread-safe합니다. 여기에는 일반 싱글톤 락 내에서 처리되는 일반적인 싱글톤 FactoryBean 인스턴스도 포함됩니다.
Destruction 콜백의 경우, 설정 상태는 thread-safe 상태를 유지하지만 초기화와 소멸 사이에 축적된 런타임 상태는 일반적인 Java 가이드라인에 따라 thread-safe한 구조(또는 단순한 경우 volatile 필드)에 보관해야 합니다.
위에서 보여준 더 깊은 Lifecycle 통합은 runnable 필드와 같이 런타임에 변경 가능한 상태를 포함하며, 이는 volatile로 선언해야 합니다. 공통 라이프사이클 콜백은 특정 순서를 따르지만(예: start 콜백은 완전한 초기화 이후에만 발생하고 stop 콜백은 초기 start 이후에만 발생), 일반적인 destroy 이전 stop arrangement에는 특수한 경우가 있습니다: 이러한 bean의 내부 상태는 이전 stop 없이 즉각적인 destroy 콜백도 허용해야 한다는 점을 강력히 권장합니다. 이는 취소된 bootstrap 이후의 비정상적인 shutdown 동안 또는 다른 bean으로 인한 stop timeout의 경우에 발생할 수 있기 때문입니다.
ApplicationContextAware and BeanNameAwareApplicationContext가 org.springframework.context.ApplicationContextAware 인터페이스를 구현하는 객체 인스턴스를 생성할 때, 해당 인스턴스는 그 ApplicationContext에 대한 reference를 제공받습니다. 다음 listing은 ApplicationContextAware 인터페이스의 정의를 보여줍니다:
1public interface ApplicationContextAware { 2 3 void setApplicationContext(ApplicationContext applicationContext) throws BeansException; 4}
따라서 bean은 ApplicationContext 인터페이스를 통해 또는 reference를 이 인터페이스의 알려진 subclass(추가 기능을 노출하는 ConfigurableApplicationContext 등)로 casting하여 자신을 생성한 ApplicationContext를 프로그래밍 방식으로 조작할 수 있습니다. 한 가지 사용 사례는 다른 bean의 프로그래밍 방식 조회입니다. 때때로 이 기능이 유용할 수 있습니다. 그러나 일반적으로는 코드를 Spring에 결합시키고 Inversion of Control 스타일(협력 객체가 프로퍼티로 bean에 제공되는 방식)을 따르지 않으므로 피해야 합니다. ApplicationContext의 다른 메서드는 파일 리소스에 대한 access, 애플리케이션 이벤트 publish, MessageSource access를 제공합니다. 이러한 추가 기능은
Additional Capabilities of the ApplicationContext에 설명되어 있습니다.
Autowiring은 ApplicationContext에 대한 reference를 얻는 또 다른 대안입니다. traditional constructor 및 byType autowiring 모드(Autowiring Collaborators에 설명됨)는 각각 constructor argument 또는 setter 메서드 parameter에 대해 ApplicationContext 타입의 의존성을 제공할 수 있습니다. 필드 및 다중 parameter 메서드를 autowire하는 기능을 포함한 더 큰 유연성을 위해 어노테이션 기반 autowiring 기능을 사용하십시오. 이를 사용하는 경우, 필드, constructor argument 또는 메서드 parameter가 ApplicationContext 타입을 기대하고 해당 필드, constructor 또는 메서드에 @Autowired 어노테이션이 있는 경우 ApplicationContext가 autowire됩니다. 자세한 내용은
Using @Autowired를 참조하십시오.
ApplicationContext가 org.springframework.beans.factory.BeanNameAware 인터페이스를 구현하는 클래스를 생성할 때, 해당 클래스는 관련 객체 정의에 정의된 이름에 대한 reference를 제공받습니다. 다음 listing은 BeanNameAware 인터페이스의 정의를 보여줍니다:
1public interface BeanNameAware { 2 3 void setBeanName(String name) throws BeansException; 4}
콜백은 일반 bean 프로퍼티의 population 이후이지만 InitializingBean.afterPropertiesSet() 또는 custom init-method와 같은 초기화 콜백 이전에 호출됩니다.
Aware InterfacesApplicationContextAware 및 BeanNameAware(앞에서 논의됨) 외에도, Spring은 bean이 컨테이너에 특정 인프라 의존성이 필요함을 나타낼 수 있도록 하는 다양한 Aware 콜백 인터페이스를 제공합니다. 일반적인 규칙으로, 이름은 의존성 타입을 나타냅니다. 다음 표는 가장 중요한 Aware 인터페이스를 요약한 것입니다:
| Name | Injected Dependency | Explained in… |
|---|---|---|
ApplicationContextAware | Declaring ApplicationContext. | ApplicationContextAware and BeanNameAware |
ApplicationEventPublisherAware | Event publisher of the enclosing ApplicationContext. | Additional Capabilities of the ApplicationContext |
BeanClassLoaderAware | Class loader used to load the bean classes. | Instantiating Beans |
BeanFactoryAware | Declaring BeanFactory. | The BeanFactory API |
BeanNameAware | Name of the declaring bean. | ApplicationContextAware and BeanNameAware |
LoadTimeWeaverAware | Defined weaver for processing class definition at load time. | Load-time Weaving with AspectJ in the Spring Framework |
MessageSourceAware | Configured strategy for resolving messages (with support for parameterization and<br>internationalization). | Additional Capabilities of the ApplicationContext |
NotificationPublisherAware | Spring JMX notification publisher. | Notifications |
ResourceLoaderAware | Configured loader for low-level access to resources. | Resources |
ServletConfigAware | Current ServletConfig the 컨테이너 runs in. Valid only in a web-aware Spring<br>ApplicationContext. | Spring MVC |
ServletContextAware | Current ServletContext the 컨테이너 runs in. Valid only in a web-aware Spring<br>ApplicationContext. | Spring MVC |
Table 1. Aware interfaces
이러한 인터페이스를 사용하면 코드가 Spring API에 결합되고 Inversion of Control 스타일을 따르지 않게 된다는 점을 다시 한 번 유의하십시오. 결과적으로, 우리는 컨테이너에 대한 프로그래밍 방식 access가 필요한 인프라 bean에 대해 이러한 인터페이스 사용을 권장합니다.
Bean Scopes
Bean Definition Inheritance