Customizing the Nature of a Bean(한글)

Spring 프레임워크는 Bean의 특성을 사용자 정의하는 데 사용할 수 있는 다양한 인터페이스를 제공하므로 특성을 사용자 정의하는 데 사용할 수 있는 다양한 인터페이스를 제공합니다. 이 섹션에서는 이러한 인터페이스를 다음과 같이 그룹화합니다:

Lifecycle 콜백(Lifecycle Callbacks)

컨테이너의 Bean 수명 주기 관리와 상호 작용하기 위해 Spring InitializingBeanDisposableBean 인터페이스를 구현할 수 있습니다. 컨테이너는 전자의 경우 afterPropertiesSet() 을 호출하고 후자의 경우 destroy() 를 호출하여 Bean이 초기화 및 소멸 시 특정 작업을 수행하도록 합니다.

JSR-250 @PostConstruct@PreDestroy 어노테이션은 일반적으로 최신 Spring 애플리케이션에서 수명 주기 콜백을 수신하기 위한 모범 사례로 간주됩니다. 이러한 어노테이션을 사용한다는 것은 Bean이 Spring 전용 인터페이스에 연결되지 않는다는 것을 의미합니다. 자세한 내용은 @PostConstruct@PreDestroy 사용을 참조하세요.

JSR-250 어노테이션을 사용하지 않으면서도 커플링을 제거하려는 경우 init-methoddestroy-method Bean 정의 메타데이터를 고려하세요.

내부적으로 Spring 프레임워크는 BeanPostProcessor 구현을 사용하여 찾을 수 있는 모든 콜백 인터페이스를 처리하고 적절한 메서드를 호출합니다. Spring이 기본적으로 제공하지 않는 사용자 정의 기능이나 기타 라이프사이클 동작이 필요한 경우 BeanPostProcessor 를 직접 구현할 수 있습니다. 자세한 내용은 컨테이너 확장 포인트를 참조하세요.

초기화 및 소멸 콜백 외에도 Spring 관리 객체는 컨테이너의 자체 라이프사이클에 따라 해당 객체가 시작 및 종료 프로세스에 참여할 수 있도록 Lifecycle 인터페이스를 구현할 수도 있습니다.

라이프사이클 콜백 인터페이스는 이 섹션에서 설명합니다.

초기화 콜백(Initialization Callbacks)

org.springframework.beans.factory.InitializingBean 인터페이스는 컨테이너가 Bean에 필요한 모든 property를 설정한 후 초기화 작업을 수행할 수 있도록 합니다. InitializingBean 인터페이스는 단일 메서드를 지정합니다:

void afterPropertiesSet() throws Exception;

InitializingBean 인터페이스는 코드를 불필요하게 Spring에 결합하므로 사용하지 않는 것이 좋습니다. 또는 @PostConstruct 어노테이션을 사용하거나 POJO 초기화 방법을 지정하는 것이 좋습니다. XML 기반 구성 메타데이터의 경우, init-method 속성을 사용하여 무인수 서명이 없는 메서드의 이름을 지정할 수 있습니다. Java 구성의 경우, @BeaninitMethod 속성을 사용할 수 있습니다. Lifecycle Callbacks 받기를 참조하세요. 다음 예제를 살펴봅시다:org.springframework.beans.factory.InitializingBean` 인터페이스는 컨테이너가 Bean에 필요한 모든 property를 설정한 후 초기화 작업을 수행할 수 있도록 합니다. InitializingBean 인터페이스는 단일 메서드를 지정합니다:

<bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/>
  • Java

  • Kotlin

public class ExampleBean {

	public void init() {
		// do some initialization work
	}
}
class ExampleBean {

	fun init() {
		// do some initialization work
	}
}

앞의 예는 다음 예(두 개의 목록으로 구성됨)와 거의 동일한 효과를 가져옵니다:

<bean id="exampleInitBean" class="examples.AnotherExampleBean"/>
  • Java

  • Kotlin

public class AnotherExampleBean implements InitializingBean {

	@Override
	public void afterPropertiesSet() {
		// do some initialization work
	}
}
class AnotherExampleBean : InitializingBean {

	override fun afterPropertiesSet() {
		// do some initialization work
	}
}

그러나 앞의 두 예제 중 첫 번째 예제에서는 코드를 Spring에 연결하지 않습니다.

일반적으로 @PostConstruct 및 초기화 메서드는 컨테이너의 싱글톤 생성 Lock 내에서 실행된다는 점에 유의하세요. Bean 인스턴스는 @PostConstruct 메서드에서 반환된 후에만 완전히 초기화되고 다른 사용자에게 게시할 준비가 된 것으로 간주됩니다. 이러한 개별 초기화 메서드는 구성 상태의 유효성을 검사하고 주어진 구성을 기반으로 일부 데이터 구조를 준비하기 위한 것일 뿐, 외부 Bean 액세스를 통한 추가 작업은 하지 않습니다. 그렇지 않으면 초기화 교착 상태가 발생할 위험이 있습니다.

비용이 많이 드는 초기화 후 활동이 트리거되어야 하는 시나리오의 경우, 예를 들어 비동기 데이터베이스 준비 단계와 같이 비용이 많이 드는 초기화 후 활동을 트리거해야 하는 시나리오의 경우, Bean은 SmartInitializingSingleton.afterSingletonsInstantiated() 를 구현하거나 ApplicationListener<ContextRefreshedEvent> 를 구현하거나 그에 해당하는 어노테이션 @EventListener(ContextRefreshedEvent.class) 를 선언하는 등 컨텍스트 새로고침 이벤트에 의존해야 합니다. 이러한 변형은 모든 일반 싱글톤 초기화 이후에 발생하므로 싱글톤 생성 Lock에서 벗어납니다.

또는 (Smart)Lifecycle 인터페이스를 구현하고 자동 시작 메커니즘, 사전 삭제 중지 단계, 잠재적인 중지/재시작 콜백을 포함한 컨테이너의 전체 수명 주기 관리와 통합할 수도 있습니다(아래 참조).

소멸 콜백(Destruction Callbacks)

org.springframework.beans.factory.DisposableBean` 인터페이스를 구현하면 Bean이 포함된 컨테이너가 소멸될 때 콜백을 받을 수 있습니다. DisposableBean 인터페이스는 단일 메서드를 지정합니다:

void destroy() throws Exception;

DisposableBean 콜백 인터페이스는 불필요하게 Spring에 코드를 결합하므로 사용하지 않는 것이 좋습니다. 또는 @PreDestroy 어노테이션을 사용하거나 Bean 정의에서 지원하는 일반 메서드를 지정하는 것이 좋습니다. XML 기반 구성 메타데이터의 경우, <bean/> 에서 destroy-method 속성을 사용할 수 있습니다. Java 구성의 경우, @BeandestroyMethod 속성을 사용할 수 있습니다. 수명 주기 콜백 받기를 참조하세요. 다음 정의를 고려하세요:

<bean id="exampleDestructionBean" class="examples.ExampleBean" destroy-method="cleanup"/>
  • Java

  • Kotlin

public class ExampleBean {

	public void cleanup() {
		// do some destruction work (like releasing pooled connections)
	}
}
class ExampleBean {

	fun cleanup() {
		// do some destruction work (like releasing pooled connections)
	}
}

앞의 정의는 다음 정의와 거의 동일한 효과를 가져옵니다:

<bean id="exampleDestructionBean" class="examples.AnotherExampleBean"/>
  • Java

  • Kotlin

public class AnotherExampleBean implements DisposableBean {

	@Override
	public void destroy() {
		// do some destruction work (like releasing pooled connections)
	}
}
class AnotherExampleBean : DisposableBean {

	override fun destroy() {
		// do some destruction work (like releasing pooled connections)
	}
}

그러나 앞의 두 정의 중 첫 번째 정의는 코드를 Spring에 결합하지 않습니다.

Spring은 또한 파괴 메서드의 추론을 지원하여 공개 close 또는 shutdown 메서드를 감지합니다. 이는 Java 구성 클래스에서 @Bean 메서드의 기본 동작이며 java.lang.AutoCloseable 또는 java.io.Closeable 구현과 자동으로 일치하며, 파괴 로직도 Spring에 결합하지 않습니다.

XML을 사용한 파괴 메서드 추론의 경우, <bean> 요소의 destroy-method 속성에 특수 (inferred) 값을 할당하여 특정 Bean 정의에 대한 Bean 클래스에서 공용 close 또는 shutdown 메서드를 자동으로 감지하도록 Spring에 지시할 수 있습니다. 또한 이 특수 (inferred) 값을 <beans> 요소의 default-destroy-method 속성에 설정하여 전체 Bean 정의 집합에 이 동작을 적용할 수도 있습니다(기본 초기화 및 삭제 메서드 참조).

확장된 종료 단계의 경우, Lifecycle 인터페이스를 구현하고 싱글톤 Bean의 파괴 메서드가 호출되기 전에 조기 중지 신호를 수신할 수 있습니다. 또한 컨테이너가 이러한 모든 중지 처리가 완료될 때까지 기다렸다가 소멸 메서드로 넘어가는 시간 제한적 중지 단계에 대해 SmartLifecycle 을 구현할 수도 있습니다.

기본 초기화 및 Destroy 메서드(Default Initialization and Destroy Methods)

Spring 전용 InitializingBeanDisposableBean 콜백 인터페이스를 사용하지 않는 초기화 및 소멸 메서드 콜백을 작성하는 경우 일반적으로 init(), initialize(), dispose() 등과 같은 이름을 가진 메서드를 작성하게 됩니다. 이러한 라이프사이클 콜백 메서드의 이름은 프로젝트 전체에서 표준화되어 모든 개발자가 동일한 메서드 이름을 사용하고 일관성을 보장하는 것이 이상적입니다.

Spring 컨테이너를 구성하여 명명된 초기화를 위해 "`look`"하도록 설정하고 모든 Bean에서 콜백 메서드 이름을 삭제할 수 있습니다. 즉, 애플리케이션 개발자는 애플리케이션 클래스를 작성하고 init() 이라는 초기화 콜백을 사용할 수 있으며, 각 Bean 정의에 init-method="init" 속성을 구성할 필요 없이 `init()`을 사용할 수 있습니다. Spring IoC 컨테이너는 Bean이 생성될 때 해당 메서드를 호출합니다(그리고 표준 수명 주기 콜백 계약 앞서 설명한)에 따라). 이 기능은 또한 초기화 및 소멸 메서드 콜백에 대해 일관된 명명 규칙을 적용합니다.

초기화 콜백 메서드의 이름이 init() 이고 소멸 콜백 메서드의 이름이 destroy() 라고 가정해 보겠습니다. 그러면 클래스는 다음 예제의 클래스와 비슷해집니다:

  • Java

  • Kotlin

public class DefaultBlogService implements BlogService {

	private BlogDao blogDao;

	public void setBlogDao(BlogDao blogDao) {
		this.blogDao = blogDao;
	}

	// this is (unsurprisingly) the initialization callback method
	public void init() {
		if (this.blogDao == null) {
			throw new IllegalStateException("The [blogDao] property must be set.");
		}
	}
}
class DefaultBlogService : BlogService {

	private var blogDao: BlogDao? = null

	// this is (unsurprisingly) the initialization callback method
	fun init() {
		if (blogDao == null) {
			throw IllegalStateException("The [blogDao] property must be set.")
		}
	}
}

그런 다음 다음과 유사한 Bean에서 해당 클래스를 사용할 수 있습니다:

<beans default-init-method="init">

	<bean id="blogService" class="com.something.DefaultBlogService">
		<property name="blogDao" ref="blogDao" />
	</bean>

</beans>

최상위 <beans/> 요소 속성에 default-init-method 속성이 있으면 Spring IoC 컨테이너가 Bean 클래스의 init 이라는 메서드를 초기화 메서드 콜백으로 인식하게 됩니다. Bean이 생성되고 어셈블될 때 Bean 클래스에 이러한 메서드가 있으면 적절한 시점에 호출됩니다.

최상위 <beans/> 요소의 default-destroy-method 속성을 사용하여 이와 유사하게(즉, XML에서) 파괴 메서드 콜백을 구성할 수 있습니다.

기존 Bean 클래스에 이미 규칙과 다르게 명명된 콜백 메서드가 있는 경우, <bean/> 자체의 init-methoddestroy-method 속성을 사용하여 메서드 이름을 지정하여(즉, XML에서) 기본값을 재정의할 수 있습니다.

Spring 컨테이너는 구성된 초기화 콜백이 모든 종속성과 함께 Bean이 제공된 직후에 호출되도록 보장합니다. 따라서 초기화 콜백은 원시 Bean 참조에서 호출되며, 이는 AOP 인터셉터 등이 아직 Bean에 적용되지 않았음을 의미합니다. 대상 Bean이 먼저 완전히 생성된 다음 해당 인터셉터 체인이 포함된 AOP 프록시(예를 들어)가 적용됩니다. 대상 Bean과 프록시가 별도로 정의된 경우, 코드가 프록시를 우회하여 원시 대상 Bean과 상호 작용할 수도 있습니다. 따라서 인터셉터를 init 메서드에 적용하는 것은 일관성이 없는데, 그렇게 하면 대상 Bean의 라이프사이클이 프록시 또는 인터셉터에 결합되고 코드가 원시 대상 Bean과 직접 상호 작용할 때 이상한 의미가 남게 되기 때문입니다.
(역자설명 : 예를 들면 AOP와 초기화 대상 빈이 별도로 구성 된 경우 대상 빈은 AOP와 상호작용을 하지 않는데, 이 때 AOP와 대상 빈의 init 메서드를 결합하게 된다면 이상한 의미를 가진 코드가 된다는 의미)

수명 주기 메커니즘 결합(Combining Lifecycle Mechanisms)

Spring 2.5부터는 Bean 라이프사이클 동작을 제어하기 위한 세 가지 옵션이 있습니다:

하나의 빈에 대해 여러 라이프사이클 메커니즘이 구성되어 있고 각 메커니즘이 다른 메서드 이름으로 구성된 경우, 구성된 각 메서드는 이 참고 사항 뒤에 나열된 순서대로 실행됩니다. 그러나 동일한 메서드 이름(예: 초기화 메서드의 경우 init())이 하나 이상의 수명 주기 메커니즘에 대해 구성된 경우, 해당 메서드는 이전 섹션에 설명된 대로 한 번만 실행됩니다.

동일한 빈에 대해 서로 다른 초기화 메서드를 사용하여 구성된 여러 수명 주기 메커니즘은 다음과 같이 호출됩니다: . @PostConstruct’로 주석이 달린 메서드 . `InitializingBean 콜백 인터페이스에 정의된 afterPropertiesSet()`로 주석이 달린 메서드. . 사용자 정의 구성된 `init() 메서드

소멸 메서드는 동일한 순서로 호출됩니다: . @PreDestroy`로 주석이 달린 메서드는 다음과 같은 순서로 호출됩니다. . `DisposableBean 콜백 인터페이스에 정의된 destroy() . . 사용자 정의 구성된 destroy() 메서드

시작 및 종료 콜백(Startup and Shutdown Callbacks)

Lifecycle 인터페이스는 자체 라이프사이클 요구 사항(예: 일부 백그라운드 프로세스 시작 및 중지)이 있는 모든 객체에 대한 필수 메서드를 정의합니다:

public interface Lifecycle {

	void start();

	void stop();

	boolean isRunning();
}

모든 Spring 관리 객체는 Lifecycle 인터페이스를 구현할 수 있습니다. 그런 다음, ApplicationContext 자체가 시작 및 중지 신호를 수신하면(예를 들어 런타임에 중지/재시작 시나리오의 경우) 해당 컨텍스트 내에 정의된 모든 Lifecycle 구현으로 해당 호출을 캐스케이드합니다. 이 작업은 다음 목록에 표시된 것처럼 LifecycleProcessor 에 위임하여 수행합니다:

public interface LifecycleProcessor extends Lifecycle {

	void onRefresh();

	void onClose();
}

LifecycleProcessor 는 그 자체로 Lifecycle 인터페이스의 확장입니다. 또한 새로고침 및 닫히는 컨텍스트에 반응하는 두 가지 다른 메서드가 추가되었습니다.

일반 org.springframework.context.Lifecycle 인터페이스는 명시적인 시작 및 중지 알림을 위한 일반 컨트랙트이며 컨텍스트 새로 고침 시간에 자동 시작을 의미하지 않는다는 점에 유의하세요. 자동 시작을 세밀하게 제어하고 특정 빈(시작 및 중지 단계 포함)을 정상적으로 중지하려면 확장된 org.springframework.context.SmartLifecycle 인터페이스를 대신 구현하는 것을 고려하세요.

또한, 종료 알림이 반드시 종료 전에 제공된다는 보장은 없습니다. 정기 종료 시 모든 Lifecycle 빈은 일반적인 소멸 콜백이 전파되기 전에 먼저 중지 알림을 받습니다. 그러나 컨텍스트의 수명 중 Hot Refresh 또는 중지된 Refresh 시도 시에는 소멸 메서드만 호출됩니다.

시작 및 종료 호출 순서는 중요할 수 있습니다. 두 객체 사이에 '종속' 관계가 존재하면 종속된 쪽이 종속된 후에 시작하고 종속된 쪽이 종속되기 전에 중지합니다. 그러나 때로는 직접적인 종속성을 알 수 없는 경우도 있습니다. 특정 유형의 객체가 다른 유형의 객체보다 먼저 시작해야 한다는 것만 알 수 있습니다. 이러한 경우 SmartLifecycle 인터페이스는 다른 옵션, 즉 상위 인터페이스인 Phased 에 정의된 대로 getPhase() 메서드를 정의합니다. 다음 목록은 Phased 인터페이스의 정의를 보여줍니다:

public interface Phased {

	int getPhase();
}

다음 목록은 SmartLifecycle 인터페이스의 정의를 보여줍니다:

public interface SmartLifecycle extends Lifecycle, Phased {

	boolean isAutoStartup();

	void stop(Runnable callback);
}

시작할 때는 위상이 가장 낮은 오브젝트가 먼저 시작됩니다. 중지할 때는 그 반대 순서를 따릅니다. 따라서 SmartLifecycle 을 구현하고 getPhase() 메서드가 Integer.MIN_VALUE 를 반환하는 객체는 가장 먼저 시작되고 가장 나중에 중지됩니다. 반대로 위상 값이 Integer.MAX_VALUE 인 경우 개체가 가장 나중에 시작되고 가장 먼저 중지되어야 함을 나타냅니다(실행 중인 다른 프로세스에 따라 달라질 수 있기 때문일 수 있음). 위상 값을 고려할 때, SmartLifecycle`을 구현하지 않는 “일반” `Lifecycle 객체의 기본 위상은 `0`이라는 점도 알아두는 것이 중요합니다. 따라서 음수 위상 값은 객체가 해당 표준 컴포넌트보다 먼저 시작하고 그 이후에 중지해야 함을 나타냅니다. 양수 위상 값은 그 반대입니다.

SmartLifecycle 에 정의된 stop 메서드는 콜백을 받습니다. 모든 구현은 해당 구현의 종료 프로세스가 완료된 후 해당 콜백의 run() 메서드를 호출해야 합니다. 이를 통해 필요한 경우 비동기 종료가 가능해지는데, 이는 LifecycleProcessor 인터페이스의 기본 구현인 DefaultLifecycleProcessor 가 각 단계 내의 개체 그룹에 대해 해당 콜백을 호출할 때까지 해당 시간 초과 값까지 기다리기 때문입니다. 단계별 기본 시간 제한은 30초입니다. 컨텍스트 내에서 lifecycleProcessor 라는 이름의 빈을 정의하여 기본 수명 주기 프로세서 인스턴스를 재정의할 수 있습니다. 타임아웃만 수정하려는 경우 다음을 정의하면 충분합니다:

<bean id="lifecycleProcessor" class="org.springframework.context.support.DefaultLifecycleProcessor">
	<!-- timeout value in milliseconds -->
	<property name="timeoutPerShutdownPhase" value="10000"/>
</bean>

앞서 언급했듯이, LifecycleProcessor 인터페이스는 컨텍스트의 컨텍스트 새로 고침 및 종료에 대한 콜백 메서드를 정의합니다. 후자는 명시적으로 호출된 것처럼 종료 프로세스를 명시적으로 호출한 것처럼 구동하지만, 컨텍스트가 닫힐 때 발생합니다. 닫을 때 발생합니다. 반면에 'refresh' 콜백은 또 다른 기능인 SmartLifecycle Bean의 또 다른 기능을 활성화합니다. 컨텍스트가 새로 고쳐질 때(모든 객체가 인스턴스화되고 인스턴스화되고 초기화된 후) 컨텍스트가 새로 고쳐지면 해당 콜백이 호출됩니다. 이 시점에서 기본 수명 주기 프로세서는 각각의 SmartLifecycle 객체의 isAutoStartup() 메서드가 반환하는 Boolean 값을 확인합니다. true 이면 해당 객체는 컨텍스트의 명시적 호출을 기다리지 않고 그 시점에서 시작되거나 자체 start() 메서드의 명시적 호출을 기다리지 않고 해당 객체가 시작됩니다(컨텍스트 새로 고침과 달리, 컨텍스트 시작은 표준 컨텍스트 구현에서는 자동으로 발생하지 않습니다). phase 값과 모든 “depends-on” 관계에 따라 앞서 설명한 대로 시작 순서가 결정됩니다.

웹이 아닌 애플리케이션에서 Spring IoC 컨테이너를 우아하게 종료하기

이 섹션은 웹 애플리케이션이 아닌 경우에만 적용됩니다. Spring의 웹 기반 ApplicationContext 구현에는 관련 웹 애플리케이션이 종료될 때 Spring IoC 컨테이너를 정상적으로 종료하는 코드가 이미 마련되어 있습니다.

웹 애플리케이션이 아닌 환경(예: 리치 클라이언트 데스크톱 환경)에서 Spring의 IoC 컨테이너를 사용하는 경우, 종료 훅을 JVM에 등록하세요. 이렇게 하면 정상적으로 종료되고 싱글톤 빈에서 관련 삭제 메서드를 호출하여 모든 리소스가 해제됩니다. 이러한 종료 콜백을 올바르게 구성하고 구현해야 합니다.

종료 훅을 등록하려면 다음 예제에서와 같이 ConfigurableApplicationContext 인터페이스에 선언된 registerShutdownHook() 메서드를 호출합니다:

  • Java

  • Kotlin

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public final class Boot {

	public static void main(final String[] args) throws Exception {
		ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");

		// add a shutdown hook for the above context...
		ctx.registerShutdownHook();

		// app runs here...

		// main method exits, hook is called prior to the app shutting down...
	}
}
import org.springframework.context.support.ClassPathXmlApplicationContext

fun main() {
	val ctx = ClassPathXmlApplicationContext("beans.xml")

	// add a shutdown hook for the above context...
	ctx.registerShutdownHook()

	// app runs here...

	// main method exits, hook is called prior to the app shutting down...
}

스레드 안전성 및 가시성(Thread Safety and Visibility)

Spring 코어 컨테이너는 생성된 싱글톤 인스턴스를 스레드 안전 방식으로 게시하여 싱글톤 잠금을 통해 액세스를 보호하고 다른 스레드에서 가시성을 보장합니다.

결과적으로 애플리케이션 제공 Bean 클래스는 초기화 상태의 가시성에 대해 걱정할 필요가 없습니다. 일반 구성 필드는 초기화 단계에서만 변경되는 한 volatile(휘발성) 으로 표시할 필요가 없으며, 초기 단계에서 변경 가능한 세터 기반 구성 상태의 경우에도 final(최종) 과 유사한 가시성을 보장합니다. 이러한 필드가 빈 생성 단계와 그 이후의 초기 게시 이후에 변경되는 경우, 해당 필드는 volatile(휘발성) 으로 선언하거나 액세스할 때마다 공통 잠금으로 보호해야 합니다.

싱글톤 빈 인스턴스에서 이러한 구성 상태에 대한 동시 액세스는, 예를 들어 컨트롤러 인스턴스나 리포지토리 인스턴스의 경우, 컨테이너 측에서 이러한 안전한 초기 게시 후에는 완벽하게 스레드 안전합니다. 여기에는 일반 싱글톤 잠금 내에서 처리되는 일반 싱글톤 FactoryBean 인스턴스도 포함됩니다.

소멸 콜백의 경우, 구성 상태는 스레드 안전하지만 초기화와 소멸 사이에 누적된 모든 런타임 상태는 일반적인 Java 지침에 따라 스레드 안전 구조(또는 간단한 경우 volatile 필드)에 보관해야 합니다.

위와 같이 보다 심층적인 Lifecycle 통합에는 runnable(실행가능) 필드와 같은 런타임 변경 가능한 상태가 포함되며, 이는 `volatile(휘발성)`으로 선언되어야 합니다. 일반적인 라이프사이클 콜백은 특정 순서를 따르지만, 예를 들어 시작 콜백은 전체 초기화 후에만 발생하고 중지 콜백은 초기 시작 후에만 발생하도록 보장되지만, 일반적인 소멸 전 중지 배열에는 특별한 경우가 있습니다: 이러한 빈의 내부 상태는 취소된 부트스트랩 후 특별한 종료 중에 발생하거나 다른 빈으로 인한 중지 시간 초과가 발생할 수 있으므로 선행 중지 없이 즉각적인 파괴 콜백을 허용할 것을 강력히 권장합니다.

ApplicationContextAware and BeanNameAware

응용 프로그램 컨텍스트`가 org.springframework.context.ApplicationContextAware 인터페이스를 구현하는 객체 인스턴스를 생성하면, 인스턴스에는 해당 ApplicationContext 에 대한 참조가 제공됩니다. 다음 목록은 ApplicationContextAware 인터페이스의 정의를 보여줍니다:

public interface ApplicationContextAware {

	void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}

따라서, Bean은 ApplicationContext 인터페이스를 통해 또는 이 인터페이스의 알려진 하위 클래스(예: 추가 기능을 노출하는 ConfigurableApplicationContext)에 대한 참조를 캐스팅하여 자신을 생성한 ApplicationContext 를 프로그래밍적으로 조작할 수 있습니다. 한 가지 용도는 다른 빈을 프로그래밍 방식으로 검색하는 것입니다. 때때로 이 기능이 유용할 수 있습니다. 그러나 일반적으로는 코드를 Spring에 결합하고 공동 작업자가 빈에 속성으로 제공되는 제어의 역전 스타일을 따르지 않기 때문에 피해야 합니다. ApplicationContext 의 다른 메서드는 파일 리소스에 대한 액세스, 애플리케이션 이벤트 게시 및 MessageSource 에 대한 액세스를 제공합니다. 이러한 추가 기능에 대한 설명은 ApplicationContext 의 추가 기능에 나와 있습니다.

자동 배선은 ApplicationContext 에 대한 참조를 얻기 위한 또 다른 대안입니다. 기존의 constructorbyType 자동 배선 모드(Autowiring Collaborators에 설명된 대로)는 각각 생성자 인수 또는 설정자 메서드 파라미터에 대해 ApplicationContext 유형의 의존성을 제공할 수 있습니다. 필드 및 여러 매개변수 메서드를 자동 와이어링하는 기능 등 더 많은 유연성을 원한다면 어노테이션 기반 Autowiring 기능을 사용하세요. 이 경우 해당 필드, 생성자 또는 메서드에 @Autowired 어노테이션이 있는 경우 ApplicationContext 유형이 예상되는 필드, 생성자 인수 또는 메서드 매개변수에 ApplicationContext`가 자동 와이어링됩니다. 자세한 내용은 @Autowired` 사용을 참조하세요.

ApplicationContextorg.springframework.beans.factory.BeanNameAware 인터페이스를 구현하는 클래스를 생성하면 해당 클래스에는 연결된 객체 정의에 정의된 이름에 대한 참조가 제공됩니다. 다음 목록은 BeanNameAware 인터페이스의 정의를 보여줍니다:

public interface BeanNameAware {

	void setBeanName(String name) throws BeansException;
}

이 콜백은 일반 Bean 프로퍼티를 채운 후 InitializingBean.afterPropertiesSet() 와 같은 초기화 콜백이나 사용자 지정 init-method 이전에 호출됩니다.

Other Aware Interfaces

ApplicationContextAwareBeanNameAware(이전 참조) 외에도 Spring은 Bean이 특정 인프라 종속성이 필요함을 컨테이너에 표시할 수 있는 광범위한 Aware 콜백 인터페이스를 제공합니다. 일반적으로 이름은 종속성 유형을 나타냅니다. 다음 표에는 가장 중요한 Aware 인터페이스가 요약되어 있습니다:

Table 1. Aware interfaces
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 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 container runs in. Valid only in a web-aware Spring ApplicationContext.

Spring MVC

ServletContextAware

Current ServletContext the container runs in. Valid only in a web-aware Spring ApplicationContext.

Spring MVC

이러한 인터페이스를 사용하면 코드가 Spring API에 연결되며 제어의 반전 스타일을 따르지 않는다는 점에 다시 한 번 유의하세요. 따라서 컨테이너에 대한 프로그래밍 방식의 액세스가 필요한 인프라 Bean에 사용하는 것이 좋습니다.