1. 程式人生 > >Spring4的知識應用總結(四)——Bean的生命週期和註解方式配置

Spring4的知識應用總結(四)——Bean的生命週期和註解方式配置

Bean的生命週期和註解方式配置

一、Bean的生命週期

        Spring IOC 容器可以管理 Bean 的生命週期, Spring 允許在 Bean 生命週期的特定點執行定製的任務. 
Spring IOC 容器對 Bean 的生命週期進行管理的過程:
通過構造器或工廠方法建立 Bean 例項
為 Bean 的屬性設定值和對其他 Bean 的引用
呼叫 Bean 的初始化方法
Bean 可以使用了
當容器關閉時, 呼叫 Bean 的銷燬方法
在 Bean 的聲明裡設定init-methoddestroy-method 屬性, 為 Bean 指定初始化和銷燬方法.

        <!--  
1. 預設情況下, IOC 容器中的 bean 是單例的! 若物件是單例的, 則在建立 IOC 容器時即建立 bean 的例項並對 bean 的屬性進行初始化. 
2. 可以通過 bean 的 scope 屬性來修改 bean 的作用域. 若取值為 prototype, 則 bean 為原型的: 每次向容器獲取例項, 得到的都是一個新的物件.
而且, 不在建立 IOC 容器時建立 bean 的例項了. 
3. IOC 容器中 bean 的生命週期: 
3.1 一般地, 討論 bean 的生命週期, 是建立在 bean 是單例的基礎上的. 
3.2 可以為 bean 指定 init 和 destroy 方法
3.3 還可以通過 bean 的後置處理器來更加豐富 bean 的生命週期方法(面試時.).
-->

<bean id="helloWorld" class="com.atguigu.spring.helloworld.HelloWorld" scope="singleton"
init-method="init"destroy-method="destroy">
<property name="userName" value="atguigu"></property>
</bean>

Bean 後置處理器

Bean 後置處理器允許在呼叫初始化方法前後對 Bean 進行額外的處理.
Bean 後置處理器對 IOC 容器裡的所有 Bean 例項逐一處理, 而非單一例項. 其典型應用是: 檢查 Bean 屬性的正確性或根據特定的標準更改 Bean 的屬性.
對Bean 後置處理器而言, 需要實現interface BeanPostProcessor
介面. 在初始化方法被呼叫前後, Spring 將把每個 Bean 例項分別傳遞給上述介面的以下兩個方法:postProcessAfterInitialization()postProcessBeforeInitialization()

新增 Bean 後置處理器後 Bean 的生命週期

       Spring IOC 容器對 Bean 的生命週期進行管理的過程:
通過構造器或工廠方法建立 Bean 例項
為 Bean 的屬性設定值和對其他 Bean 的引用
將 Bean 例項傳遞給 Bean 後置處理器的 postProcessBeforeInitialization 方法
呼叫 Bean 的初始化方法
將 Bean 例項傳遞給 Bean 後置處理器的 postProcessAfterInitialization方法

Bean 可以使用了
當容器關閉時, 呼叫 Bean 的銷燬方法

二、其他方式配置Bean

實現 FactoryBean 介面在 Spring IOC 容器中配置 Bean

Spring 中有兩種型別的 Bean, 一種是普通Bean, 另一種是工廠Bean, 即FactoryBean
工廠 Bean 跟普通Bean不同, 其返回的物件不是指定類的一個例項, 其返回的是該工廠 Bean 的 getObject方法所返回的物件 
public class CarFacotryBean implements FactoryBean{  
private String brand;  
public void setBrand(String brand)  
{this.brand = brand; }  
@Override  
public Object getObject() throws Exception{}

@Override  
public Class getObjectType(){}  

<!--通過FactoryBean來配置bean的例項  
    class:指向自定義的CarFacotryBean  
property:配置CarFacotryBean的屬性,  
實際返回的例項是CarFacotryBean的getObject()方法返回的例項  
 -->  

<bean id = "car" class="com.bean.factory.CarFacotryBean">  
<property name="brand" value = "Bas"></property>  
</bean> 

三、基於註解配置Bean和Bean的屬性

在 classpath 中掃描元件

        元件掃描(component scanning):  Spring 能夠從 classpath 下自動掃描, 偵測和例項化具有特定註解的元件. 
特定元件包括:
@Component: 基本註解, 標識了一個受 Spring 管理的元件
@Respository: 標識持久層元件
@Service: 標識服務層(業務層)元件
@Controller: 標識表現層元件
對於掃描到的元件,Spring 有預設的命名策略: 使用非限定類名, 第一個字母小寫.也可以在註解中通過 value 屬性值標識元件的名稱
當在元件類上使用了特定的註解之後, 還需要在 Spring 的配置檔案中宣告<context:component-scan>
base-package 屬性指定一個需要掃描的基類包,Spring 容器將會掃描這個基類包裡及其子包中的所有類. 
當需要掃描多個包時, 可以使用逗號分隔.
如果僅希望掃描特定的類而非基包下的所有類,可使用 resource-pattern 屬性過濾特定的類,示例:
<context:include-filter> 子節點表示要包含的目標類
<context:exclude-filter> 子節點表示要排除在外的目標類
<context:component-scan> 下可以擁有若干個 <context:include-filter> 和 <context:exclude-filter> 子節點
<context:include-filter> 和 <context:exclude-filter> 子節點支援多種型別的過濾表示式:annotation  assinable aspectj regex custom(前面兩個很常用)

元件裝配

<context:component-scan> 元素還會自動註冊 AutowiredAnnotationBeanPostProcessor 例項, 該例項可以自動裝配具有@Autowired 和 @Resource 、@Inject註解的屬性.

使用 @Autowired 自動裝配 Bean

@Autowired 註解自動裝配具有相容型別的單個 Bean屬性
構造器, 普通欄位(即使是非 public), 一切具有引數的方法都可以應用@Authwired 註解
預設情況下, 所有使用 @Authwired 註解的屬性都需要被設定. 當 Spring 找不到匹配的 Bean 裝配屬性時, 會丟擲異常, 若某一屬性允許不被設定, 可以設定 @Authwired 註解的 required 屬性為 false
預設情況下, 當 IOC 容器裡存在多個型別相容的 Bean 時, 通過型別的自動裝配將無法工作. 此時可以在 @Qualifier 註解裡提供 Bean 的名稱. Spring 允許對方法的入參標註 @Qualifiter 已指定注入 Bean 的名稱
@Authwired 註解也可以應用在陣列型別的屬性上, 此時 Spring 將會把所有匹配的 Bean 進行自動裝配.
@Authwired 註解也可以應用在集合屬性上, 此時 Spring 讀取該集合的型別資訊, 然後自動裝配所有與之相容的 Bean. 
@Authwired 註解用在java.util.Map 上時, 若該 Map 的鍵值為 String, 那麼 Spring 將自動裝配與之 Map 值型別相容的 Bean, 此時 Bean 的名稱作為鍵值

使用 @Resource 或 @Inject 自動裝配 Bean

Spring 還支援 @Resource 和 @Inject 註解,這兩個註解和 @Autowired 註解的功用類似
@Resource 註解要求提供一個 Bean 名稱的屬性,若該屬性為空,則自動採用標註處的變數或方法名作為 Bean 的名稱
@Inject 和 @Autowired 註解一樣也是按型別匹配注入的 Bean, 但沒有 reqired 屬性
建議使用 @Autowired 註解