6、IOC 之自定義Bean屬性
Spring架構提供了許多接口,您可以使用它們來自定義 Bean 的性質。本部分将它們分組如下:
- 生命周期回調
-
和ApplicationContextAware
BeanNameAware
- 其他
接口Aware
6.1、生命周期回調
要與容器對 Bean 生命周期的管理進行互動,可以實作 Spring 的
InitializingBean
和
DisposableBean
接口。容器要求前者和後者讓bean在
afterPropertiesSet()
初始化和
destroy()
銷毀bean時執行某些操作。
JSR-250和
@PostConstruct
注釋通常被認為是在現代 Spring 應用程式中接收生命周期回調的最佳實踐。使用這些注釋意味着您的 Bean 不會耦合到特定于 Spring 的接口。有關詳細資訊,請參閱使用
@PreDestroy
和
@PostConstruct
@PreDestroy
。
如果不想使用 JSR-250 注釋,但仍要删除耦合,請考慮
和
init-method
來定義 Bean 中繼資料。
destroy-method
① 初始化回調
org.springframework.beans.factory.InitializingBean
該接口允許 Bean 在容器上設定了所有必要的屬性後執行初始化工作
package org.springframework.beans.factory;
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
◆ 注意點:
- 官方不建議使用該回調接口,因為它會不必要地将代碼耦合到Spring
- 建議使用
注釋或指定 POJO 初始化方法@PostConstruct
- 對于基于 XML 的配置中繼資料,可以使用
屬性指定具有 void 無參數簽名的方法的名稱init-method
- 使用 Java 配置,可以使用
的@Bean
屬性initMethod
- 對于基于 XML 的配置中繼資料,可以使用
② 銷毀回調
org.springframework.beans.factory.DisposableBean
實作該接口允許 Bean 在包含它的容器被銷毀時獲得回調
package org.springframework.beans.factory;
public interface DisposableBean {
void destroy() throws Exception;
}
◆ 注意點:
- 官方不建議使用該回調接口,因為它不必要地将代碼耦合到Spring
- 建議使用
注釋或指定 Bean 定義支援的泛型方法@PreDestroy
- 對于基于 XML 的配置中繼資料,可以使用
上的<bean/>
屬性destroy-method
- 使用 Java 配置,可以使用
的@Bean
屬性destroyMethod
- 對于基于 XML 的配置中繼資料,可以使用
③ 預設初始化和銷毀方法
相當于定義一個初始化和銷毀的規範。
比如
<beans/>
裡所有bean類内都定義了(有就調沒有就拉倒)初始化和銷毀方法都叫
init()
和
destroy()
,這樣我們就可以使用
<beans/>
的兩個屬性:
default-init-method="init"
和
default-destroy-method="destroy"
<beans default-init-method="init" default-destroy-method="destroy">
<bean id="blogService" class="com.xxx.DefaultBlogService"/>
<bean id="otherService" class="com.xxx.OtherService"/>
</beans>
④ 組合生命周期機制
從 Spring 2.5 開始,您有三個選項來控制 Bean 生命周期行為:
- 回調接口
和InitializingBean
DisposableBean
- 定制
和init()
方法destroy()
-
和@PostConstruct
注解;你可以組合這些機制來控制給定的 Bean@PreDestroy
如果為 Bean 配置了多個生命周期機制,并且每個機制都配置了不同的方法名稱,則每個配置的方法将按本說明之後(下面)列出的順序運作。但是,如果為多個這些生命周期機制配置了相同的方法名稱(例如,初始化方法 init()
),則該方法将運作一次,如上一節所述。
1、為同一 Bean 配置的具有不同初始化方法的多個生命周期機制的調用方式如下:
- 用
注釋的方法@PostConstruct
- 由回調接口
定義的InitializingBean
afterPropertiesSet()
- 自定義配置的
方法init()
2、銷毀方法的調用順序相同:
- 用
注釋的方法@PreDestroy
- 由回調接口
定義的DisposableBean
destroy()
- 自定義配置的
方法destroy()
④ 啟動和關閉回調
該接口為具有自己的生命周期要求(例如啟動和停止某些背景程序)的任何對象定義了基本方法:
Lifecycle
package org.springframework.context;
public interface Lifecycle {
void start();
void stop();
boolean isRunning();
}
任何 Spring 管理的對象都可以實作該接口。然後,當自身接收到啟動和停止信号(例如,對于運作時的停止/重新啟動方案)時,它會将這些調用級聯到該上下文中定義的所有實作。
package org.springframework.context;
public interface LifecycleProcessor extends Lifecycle {
void onRefresh();
void onClose();
}
請注意,
LifecycleProcessor
本身是
Lifecycle
接口的擴充。它還添加了另外兩種方法,用于對正在重新整理和關閉的上下文做出反應。
其餘内容可直接通路 官方文檔
⑤ 在非 Web 應用程式中優雅地關閉春季 IoC 容器
本小節内容可直接通路 官方文檔
6.2、 ApplicationContextAware
和 BeanNameAware
ApplicationContextAware
BeanNameAware
當
ApplicationContext
建立實作
org.springframework.context.ApplicationContextAware
接口的對象執行個體時,将為該執行個體提供對該
ApplicationContextAware
的引用。
package org.springframework.context;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.Aware;
public interface ApplicationContextAware extends Aware {
void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}
是以,bean 可以通過
ApplicationContext
接口或通過将引用轉換為該接口的已知子類(例如
ConfigurableApplicationContext
,它公開附加功能)以程式設計方式操作建立它們的
ApplicationContext
。一種用途是對其他 bean 進行程式設計檢索。有時,此功能很有用。但是,通常應該避免使用它,因為它将代碼與 Spring 耦合,并且不遵循 IoC,其中協作者作為屬性提供給 bean。
ApplicationContext
的其他方法提供對檔案資源的通路、釋出應用程式事件和通路
MessageSource
。這些附加功能在
ApplicationContext
的附加功能中進行了描述。
從 Spring 2.5 開始,自動裝配是擷取
ApplicationContext
引用的另一種方法。 “傳統”構造函數和 byType 自動裝配模式(如 Autowiring Collaborators 中所述)可以分别為構造函數參數或 setter 方法參數提供
ApplicationContext
類型的依賴關系。要獲得更大的靈活性,包括自動裝配字段和多個參數方法的能力,請使用新的基于注釋的自動裝配功能。如果這樣做,
ApplicationContext
将自動裝配到需要
ApplicationContext
類型的字段、構造函數參數或方法參數中,前提是相關字段、構造函數或方法帶有
@Autowired
注釋。
當
ApplicationContext
建立一個實作
org.springframework.beans.factory.BeanNameAware
接口的類時,該類将提供對其關聯對象定義中定義的名稱的引用。
package org.springframework.beans.factory;
public interface BeanNameAware extends Aware {
void setBeanName(String name);
}
在填充正常的bean屬性之後,但在初始化回調(例如
InitializingBean.afterPropertiesSet
或自定義init-method)之前,調用該回調。
6.3、其他 Aware
接口
Aware
除了
ApplicationContextAware
和
BeanNameAware
之外,Spring還提供了多種Aware回調接口,這些接口使Bean向容器訓示它們需要某種基礎結構依賴性。 通常,名稱表示依賴項類型。 下表總結了最重要的Aware接口:
Name | Injected Dependency | Explained in… |
---|---|---|
| 聲明 | 和 |
| 封閉 的事件釋出者 | 的其他功能 |
| 用于加載 Bean 類的類加載器 | 執行個體化Bean |
| 聲明 | API |
| 聲明 Bean 的名稱 | 和 |
| 定義了用于在加載時處理類定義的編織器 | 在Spring架構中使用AspectJ進行加載時間編織 |
| 已配置的消息解析政策(支援參數化和國際化) | 的附加功能 |
| Spring JMX 通知釋出者 | 通知 |
| 為資源的低級通路配置了加載器 | 資源 |
| 容器運作的目前 。僅在web感覺的Spring 中有效 | Spring MVC |
| 容器運作的目前 。僅在web感覺的Spring 中有效 | Spring MVC |
再次注意,使用這些接口會将你的代碼與Spring API綁定在一起,并且不遵循IOC。 官方建議将它們用于需要以程式設計方式通路容器的基礎結構 Bean。