追蹤
在城市的一角低調喧嘩。
關於部落格
在數位的城市裡,尋找那遺落各地一點一滴的人文元素。
  • 116966

    累積人氣

  • 3

    今日人氣

    5

    追蹤人氣

[Spring技術手冊] 筆記(4) - Spring Bean的生命週期

Aware介面

在上述程序中,提到了一些xxxAware介面,所謂的Aware介面就是讓某個Bean類別實作後,可以取用一些Spring的相關資源,但如此一來,就會使得邏輯程式與容器API之間有耦合性產生。但為了方便取用,有時候還是可以設定Aware介面,讓邏輯程式「察覺」Spring容器的存在。

在此介紹三個Aware介面:
BeanNameAware
BeanFactoryAware
ApplicationContextAware



1. BeanNameAware
在上述第3個流程中,若有實作BeanNameAware介面,則可透過setBeanName()方法取得該bean實例在bean定義檔中的設定名稱。其介面定義如下:
public interface BeanNameAware {
        public void setBeanName(String name);
}
因此要在實作此介面的類別,去override這個method,例如可設定一個private String beanName;
然後在此方法內將注入的beanName設值到this.beanName中:
public void setBeanName(String beanName){
        this.beanName = beanName;
}

2. BeanFactoryAware
在上述第4個流程中,若有實作BeanFactoryAware介面,則可透過setBeanFactory()方法取得beanFactory的實例。其介面定義如下:
public interface BeanFactoryAware {
        public void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}
與上述相同,可設定一個private BeanFactory beanFactory來接取得beanFactory實例。

3. ApplicationContextAware
在上述第4a流程中,若有實作ApplicationContextAware介面,則可透過setApplicationContext()方法取得applicationContext的實例。其介面定義如下:
public interface ApplicationContextAware{
        public void setApplicationContext(ApplicationContext context) throws BeansException;
}
與上述相同,可設定一個private ApplicationContext context來接取得applicationContext實例。



在Bean實例「初始化」前/後做點什麼吧

在bean生命週期流程中,看到第5與第8點有提到一個BeanPostProcessor介面,分別會執行postProcessBeforeInitialization()與postProcessAfterInitialization()方法。其執行的時機點,會在屬性注入之後,以及在「初始化」方法的前與後執行。所謂的初始化方法是指上述生命週期流程的第6(InitializationBean的afterPropertiesSet()方法)或第7點(自定義的init-method方法)。

其介面定義如下:
public interface BeanPostProcessor{
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

其中傳入兩個參數,第一個bean參數是已經注入屬性的bean實例,第二個參數是bean實例在Bean定義檔中的名稱。無論處理不處理,都要回傳一個Object物件,也就是bean實例。因此,只要implements了BeanPostProcessor介面,若沒有做修改至少也要將bean原封不動的return回去。

作者良葛格在此舉了一個將所有"String"類別的屬性都轉換成英文大寫的機制,使用了reflection來實作,看的出作者功力深厚,但在此不免有點殺雞焉用牛刀之味。因為倘若原本設計者就知道Bean類別中有什麼field,只要直接將參數bean做casting,轉回原本Bean的類別,再直接就其field做處理亦可。不過作者的作法是一體適用較有彈性沒錯,在此也不得不誇講一番。
相簿設定
標籤設定
相簿狀態