在前一篇文章中,我們已經介紹了 Spring IOC 的相關知識,今天將為個位介紹 Spring 中 Bean 的相關知識。關註我的公眾號「Java面典」,每天 10:24 和你一起瞭解更多 Java 相關知識點。 Bean 的生命周期 Spring 生命周期有四個階段,分別是: 1. 實例化 In ...
在前一篇文章中,我們已經介紹了 Spring IOC 的相關知識,今天將為個位介紹 Spring 中 Bean 的相關知識。關註我的公眾號「Java面典」,每天 10:24 和你一起瞭解更多 Java 相關知識點。
Bean 的生命周期
Spring 生命周期有四個階段,分別是:
- 實例化 Instantiation
- 屬性賦值 Populate
- 初始化 Initialization
- 銷毀 Destruction
實例化
通過構造器或工廠方法創建 Bean 實例,也就是我們常說的給自己 new 一個對象。
屬性賦值
為 Bean 的屬性設置值和對其他 Bean 的引用,主要涉及以下幾個方面的內容:
- IOC 依賴註入:按照 Spring 上下文對實例化的 Bean 進行配置,也就是 IOC 註入;
- setBeanName 實現:如果這個 Bean 已經實現了 BeanNameAware 介面,會調用它實現的 setBeanName(String)方法,此處傳遞的就是 Spring 配置文件中 Bean 的 id 值;
- BeanFactoryAware 實現:如果這個 Bean 已經實現了 BeanFactoryAware 介面,會調用它實現的 setBeanFactory,setBeanFactory(BeanFactory)傳遞的是 Spring 工廠自身(可以用這個方式來獲取其它 Bean,只需在 Spring 配置文件中配置一個普通的 Bean 就可以);
- ApplicationContextAware 實現:如果這個 Bean 已經實現了 ApplicationContextAware 介面,會調用setApplicationContext(ApplicationContext)方法,傳入 Spring 上下文(同樣這個方式也可以實現步驟 4 的內容,但比 4 更好,因為 ApplicationContext 是 BeanFactory 的子介面,有更多的實現方法);
- postProcessBeforeInitialization 介面實現-初始化預處理:如果這個 Bean 關聯了 BeanPostProcessor 介面,將會調用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor 經常被用作是 Bean 內容的更改,並且由於這個是在 Bean 初始化結束時調用那個的方法,也可以被應用於記憶體或緩存技術。
初始化
- init-method:如果 Bean 在 Spring 配置文件中配置了 init-method 屬性會自動調用其配置的初始化方法;
- postProcessAfterInitialization:如果這個 Bean 關聯了 BeanPostProcessor 介面,將會調用postProcessAfterInitialization(Object obj, String s)方法。
註:以上工作完成以後就可以應用這個 Bean 了,那這個 Bean 是一個 Singleton 的,所以一般情況下我們調用同一個 id 的 Bean 會是在內容地址相同的實例,當然在 Spring 配置文件中也可以配置非 Singleton。
銷毀
destroy:當 Bean 不再需要時,會經過清理階段,如果 Bean 實現了 DisposableBean 這個介面,會調用其實現的 destroy() 方法;
bean 標簽有兩個重要的屬性(init-method 和 destroy-method),可以來自定義初始化和註銷方法,其對應的註解分別是 @PostConstruct 和 @PreDestroy。
<bean id="" class="" init-method="初始化方法" destroy-method="銷毀方法">
Spring Bean 作用域
Spring 中為 Bean 定義了 5 中作用域,分別為 singleton(單例)、prototype(原型)、request(請求)、session(會話) 和 global session(全局會話),5 種作用域說明如下:
singleton (單例模式)
Spring IOC 容器中只會存在一個共用的 Bean 實例,無論有多少個 Bean 引用它,始終指向同一對象。Singleton 作用域是 Spring 中的預設作用域,也可以顯示的將 Bean 定義為 singleton 模式,配置為:
<bean id="userDao" class="com.ioc.UserDaoImpl" scope="singleton"/>
該模式在多線程下是不安全的。
prototype(原型模式)
每次通過 Spring 容器獲取 prototype 定義的 bean 時,容器都將創建一個新的 Bean 實例,每個 Bean 實例都有自己的屬性和狀態,而 singleton 全局只有一個對象。
一般而言,對有狀態的 Bean 使用 prototype 作用域,而對無狀態的 Bean 使用 singleton 作用域。
request(單次請求模式)
在一次 Http 請求中,容器會返回該 Bean 的同一實例。而對不同的 Http 請求則會產生新的 Bean,而且該 Bean 僅在當前 Http Request 內有效,當前 Http 請求結束,該 bean實例也將會被銷毀。
<bean id="loginAction" class="com.cnblogs.Login" scope="request"/>
session(會話模式)
在一次 Http Session 中,容器會返回該 Bean 的同一實例。而對不同的 Session 請求則會創建新的實例,該 Bean 實例僅在當前 Session 內有效。同 Http 請求相同,每一次 Session 請求創建新的實例,而不同的實例之間不共用屬性,且實例僅在自己的 Session 請求內有效,請求結束,則實例將被銷毀。
<bean id="userPreference" class="com.ioc.UserPreference" scope="session"/>
global Session(全局會話模式)
global Session:在一個全局的 Http Session 中,容器會返回該 Bean 的同一個實例,僅在使用 portlet context 時有效。