雲栖号資訊:【 點選檢視更多行業資訊】
在這裡您可以找到不同行業的第一手的上雲資訊,還在等什麼,快來!
在Spring中,Bean是最基礎的對象,一切操作都是圍繞Bean展開的。Spring是一個BOP(Bean Oriented Programming)架構,Bean在BOP中的作用就像是對象在OOP中的作用一樣。既然如此重要,那麼我們首先需要了解到底什麼是Bean?
什麼是Bean
首先,我們來看看Spring官方文檔對于Bean的定義:
從上面可知,我們可以給Bean下一個定義:Bean就是由IOC執行個體化、組裝、管理的一個對象。
Bean的生命周期
我們需要明确的是,在這裡我們的Bean的生命周期主要指的是singleton bean,對prototype bean來說,當使用者getBean獲得prototype bean的執行個體後,IOC容器就不再對目前執行個體進行管理,而是把管理權交由使用者,此後再getBean生成的是新的執行個體。對于request/session/application/websocket 這幾種scope的bean我們在此不談。
在不同的容器中,Bean的生命周期開始的時間不同。對于ApplicationContext來說,當容器啟動的時候,bean就已經執行個體化了。而對于BeanFactory來說,直到調用getBean()方法的時候才進行執行個體化。
我們知道對于普通的java對象來說,它們的生命周期就是
- 執行個體化
- 不再使用的時候通過垃圾回收機制進行回收
但是對于Bean來說卻不是這樣。Bean的生命周期如下圖所示
對于如上這些方法,我們可以分成如下幾類
1.Bean自身的方法:比如構造函數、getter/setter以及init-method和destory-method所指定的方法等
2.Bean級生命周期方法:可以了解為Bean類直接實作接口的方法,比如BeanNameAware、BeanFactoryAware、ApplicationContextAware、InitializingBean、DisposableBean等方法,這些方法隻對目前Bean生效
3.容器級的方法(BeanPostProcessor一系列接口):主要是後處理器方法,比如上圖的InstantiationAwareBeanPostProcessor、BeanPostProcessor接口方法。這些接口的實作類是獨立于bean的,并且會注冊到Spring容器中。在Spring容器建立任何Bean的時候,這些後處理器都會發生作用。
4.工廠後處理器方法(BeanFactoryProcessor一系列接口):包括AspectJWeavingEnabler、CustomAutowireConfigurer、ConfigurationClassPostProcessor等。這些都是Spring架構中已經實作好的BeanFactoryPostProcessor,用來實作某些特定的功能。
Bean自身的方法和Bean級生命周期方法都隻對目前Bean起作用,但是容器級生命周期方法和工廠後處理器方法是對所有的bean都起作用。
對于這幾類方法,1 2 4都很好了解,下面我們重點來說一下什麼是BeanPostProcessor和BeanFactoryPostProcessor
以我個人了解來說,BeanPostProcessor和BeanFactoryPostProcessor就是Spring建立的擴充點,使用者可以建立自己的實作類來修改Bean或者BeanFactory
注意對于ApplicatonContext來說,容器可以自動檢測并加載BeanPostProcessor和BeanFactoryPostProcessor,但是BeanFactory不行,需要自己調用方法手動注冊。BeanPostProcessor和BeanFactoryPostProcessor都可以有多個。ApplicationContext也可以根據org.springframework.core.PriorityOrdered和org.springframework.core.Ordered來進行自定義排序,但是BeanFactory不可以,預設順序就是注冊順序。
這裡我需要說明下面兩個容易混淆的單詞:
- Instantiation:執行個體化,指的是調用構造函數進行執行個體化
- Initialization:初始化,在Bean的聲明周期中指的是init-method所指定的方法或者是InitializingBean.afterPropertiesSet()方法
下面我們對常用的這些接口進行說明:
常用接口說明
1.BeanNameAware
該接口隻有一個方法setBeanName(String name),用來擷取bean的id或者name
2.BeanFactoryAware
該接口隻有一個方法setBeanFactory(BeanFactory beanFactory),用來擷取目前環境中的BeanFactory
3.ApplicationContextAware
該接口隻有一個方法setApplicationContext(ApplicationContext applicationContext),用來擷取目前環境中的ApplicationContext
擷取到IOC容器之後,可以對beans進行修改等操作
4.InitializingBean
該接口隻有一個方法afterPropertiesSet(),在屬性注入完成後調用
5.DisposableBean
該接口隻有一個方法destroy(),在容器銷毀的時候調用,在使用者指定的destroy-method之前調用
6.BeanPostProcessor該接口有兩個方法:
- postProcessBeforeInitialization(Object bean, String beanName):在初始化之前調用此方法
- postProcessAfterInitialization(Object bean, String beanName):在初始化之後調用此方法
通過方法簽名我們可以知道,我們可以通過beanName來篩選出我們需要進行個性化定制的bean
7.InstantiationAwareBeanPostProcessor
該類是BeanPostProcessor的子接口,常用的有如下三個方法
- postProcessBeforeInstantiation(Class beanClass, String beanName):在bean執行個體化之前調用
- postProcessProperties(PropertyValues pvs, Object bean, String beanName):在bean執行個體化之後、設定屬性前調用
- postProcessAfterInstantiation(Class beanClass, String beanName):在Bean執行個體化之後調用
測試Bean生命周期
下面我們來編寫一個執行個體來驗證我們上面所說的Bean生命周期
首先,我們建立一個User,這個Bean實作了我們的BeanNameAware、ApplicationContextAware、InitializingBean、DisposableBean接口
然後我們實作我們自己的BeanPostProcessor
實作自己的InstantiationAwareBeanPostProcessor
xml配置檔案如下
編寫我們自己的測試類
最後運作項目
【雲栖号線上課堂】每天都有産品技術專家分享!
課程位址:
https://yqh.aliyun.com/live立即加入社群,與專家面對面,及時了解課程最新動态!
【雲栖号線上課堂 社群】
https://c.tb.cn/F3.Z8gvnK
原文釋出時間:2020-04-28
本文作者:寫西瓜的Code
本文來自:“
掘金”,了解相關資訊可以關注“掘金”