天天看點

6、IOC 之自定義Bean屬性6、IOC 之自定義Bean屬性

6、IOC 之自定義Bean屬性

Spring架構提供了許多接口,您可以使用它們來自定義 Bean 的性質。本部分将它們分組如下:

  • 生命周期回調
  • ApplicationContextAware

    BeanNameAware

  • 其他

    Aware

    接口

6.1、生命周期回調

要與容器對 Bean 生命周期的管理進行互動,可以實作 Spring 的

InitializingBean

DisposableBean

接口。容器要求前者和後者讓bean在

afterPropertiesSet()

初始化和

destroy()

銷毀bean時執行某些操作。

JSR-250

@PostConstruct

@PreDestroy

注釋通常被認為是在現代 Spring 應用程式中接收生命周期回調的最佳實踐。使用這些注釋意味着您的 Bean 不會耦合到特定于 Spring 的接口。有關詳細資訊,請參閱使用

@PostConstruct

@PreDestroy

如果不想使用 JSR-250 注釋,但仍要删除耦合,請考慮

init-method

destroy-method

來定義 Bean 中繼資料。

① 初始化回調

org.springframework.beans.factory.InitializingBean

該接口允許 Bean 在容器上設定了所有必要的屬性後執行初始化工作

package org.springframework.beans.factory;
public interface InitializingBean {
	void afterPropertiesSet() throws Exception;
}
           

◆ 注意點:

  • 官方不建議使用該回調接口,因為它會不必要地将代碼耦合到Spring
  • 建議使用

    @PostConstruct

    注釋或指定 POJO 初始化方法
    • 對于基于 XML 的配置中繼資料,可以使用

      init-method

      屬性指定具有 void 無參數簽名的方法的名稱
    • 使用 Java 配置,可以使用

      @Bean

      initMethod

      屬性
      6、IOC 之自定義Bean屬性6、IOC 之自定義Bean屬性

② 銷毀回調

org.springframework.beans.factory.DisposableBean

實作該接口允許 Bean 在包含它的容器被銷毀時獲得回調

package org.springframework.beans.factory;
public interface DisposableBean {
	void destroy() throws Exception;
}
           

◆ 注意點:

  • 官方不建議使用該回調接口,因為它不必要地将代碼耦合到Spring
  • 建議使用

    @PreDestroy

    注釋或指定 Bean 定義支援的泛型方法
    • 對于基于 XML 的配置中繼資料,可以使用

      <bean/>

      上的

      destroy-method

      屬性
    • 使用 Java 配置,可以使用

      @Bean

      destroyMethod

      屬性
      6、IOC 之自定義Bean屬性6、IOC 之自定義Bean屬性

③ 預設初始化和銷毀方法

相當于定義一個初始化和銷毀的規範。

比如

<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

    @PreDestroy

    注解;你可以組合這些機制來控制給定的 Bean
如果為 Bean 配置了多個生命周期機制,并且每個機制都配置了不同的方法名稱,則每個配置的方法将按本說明之後(下面)列出的順序運作。但是,如果為多個這些生命周期機制配置了相同的方法名稱(例如,初始化方法

init()

),則該方法将運作一次,如上一節所述。

1、為同一 Bean 配置的具有不同初始化方法的多個生命周期機制的調用方式如下:

  1. @PostConstruct

    注釋的方法
  2. 由回調接口

    InitializingBean

    定義的

    afterPropertiesSet()

  3. 自定義配置的

    init()

    方法

2、銷毀方法的調用順序相同:

  1. @PreDestroy

    注釋的方法
  2. 由回調接口

    DisposableBean

    定義的

    destroy()

  3. 自定義配置的

    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

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

接口

除了

ApplicationContextAware

BeanNameAware

之外,Spring還提供了多種Aware回調接口,這些接口使Bean向容器訓示它們需要某種基礎結構依賴性。 通常,名稱表示依賴項類型。 下表總結了最重要的Aware接口:

Name Injected Dependency Explained in…

ApplicationContextAware

聲明

ApplicationContext

ApplicationContextAware

BeanNameAware

ApplicationEventPublisherAware

封閉

ApplicationContext

的事件釋出者

ApplicationContext

的其他功能

BeanClassLoaderAware

用于加載 Bean 類的類加載器 執行個體化Bean

BeanFactoryAware

聲明

BeanFactory

BeanFactory

API

BeanNameAware

聲明 Bean 的名稱

ApplicationContextAware

BeanNameAware

LoadTimeWeaverAware

定義了用于在加載時處理類定義的編織器 在Spring架構中使用AspectJ進行加載時間編織

MessageSourceAware

已配置的消息解析政策(支援參數化和國際化)

ApplicationContext

的附加功能

NotificationPublisherAware

Spring JMX 通知釋出者 通知

ResourceLoaderAware

為資源的低級通路配置了加載器 資源

ServletConfigAware

容器運作的目前

ServletConfig

。僅在web感覺的Spring

ApplicationContext

中有效
Spring MVC

ServletContextAware

容器運作的目前

ServletContext

。僅在web感覺的Spring

ApplicationContext

中有效
Spring MVC

再次注意,使用這些接口會将你的代碼與Spring API綁定在一起,并且不遵循IOC。 官方建議将它們用于需要以程式設計方式通路容器的基礎結構 Bean。