【79期】別找了,回答Spring中Bean的生命周期,這里幫你總結(jié)好了!
閱讀本文大概需要 5?分鐘。
來自:juejin.im/post/5a4ee1f6518825733e603fcb
ApplicationContext中Bean的生命周期

圖中綠色箭頭的三個步驟(InstantiationAwareBeanPostProcessor)和粉紅色箭頭的兩個步驟(BeanPostProcessor)為容器級的生命周期接口,當(dāng)Spring每加載任何一個Bean到容器中時,這些接口都會起到如圖中的幾次調(diào)用。這兩個處理器叫做"容器級后處理器",他們的影響是全局的,能夠影響所有的Bean.
圖中大紅色圓圈圈住的接口叫做"工廠級后處理器",類似的接口還有CustomEditorConfigurer,PropertyPlaceholderConfigurer等,這類接口只在上下文初始化的時候調(diào)用一次,其目的是完成一些配置文件的加工處理工作。
剩下的就簡單了,屬于Bean級別的接口,專屬于某個Bean所有,每個Bean實例化的時候調(diào)用自己特有的。
這些接口的調(diào)用順序并不是一塵不變的,會隨便Spring的版本變動而變動,大家要做的是萬變不離其宗,知道能夠通過這些接口在Bean初始化的時做一些屬性上的操作。調(diào)用順序要根據(jù)具體的版本來自己測試。下面我會給大家來列一個例子:
public?class?Student?implements?BeanFactoryAware,?BeanNameAware,
????????InitializingBean,?DisposableBean,ApplicationContextAware?{
????private?String?name;
????public?Student(String?name)?{
????????this.name?=?name;
????}
????public?String?getName()?{
????????return?name;
????}
????public?void?setName(String?name)?{
????????this.name?=?name;
????}
????@Override
????public?void?setBeanFactory(BeanFactory?beanFactory)?throws?BeansException?{
????????System.out.println("BeanFactoryAware......");
????}
????@Override
????public?void?setBeanName(String?s)?{
????????System.out.println("BeanNameAware......");
????}
????@Override
????public?void?destroy()?throws?Exception?{
????????System.out.println("DisposableBean......");
????}
????@Override
????public?void?afterPropertiesSet()?throws?Exception?{
????????System.out.println("InitializingBean......");
????}
????@Override
????public?void?setApplicationContext(ApplicationContext?applicationContext)?throws?BeansException?{
????????System.out.println("ApplicationContextAware......");
????}
}
public?class?MyBeanFactoryPostProcessor?implements?BeanFactoryPostProcessor?{
????public?MyBeanFactoryPostProcessor()?{
????????super();
????????System.out.println("這是BeanFactoryPostProcessor實現(xiàn)類構(gòu)造器??!");
????}
????@Override
????public?void?postProcessBeanFactory(ConfigurableListableBeanFactory?arg0)
????????????throws?BeansException?{
????????System.out.println("BeanFactoryPostProcessor調(diào)用postProcessBeanFactory方法");
????????BeanDefinition?bd?=?arg0.getBeanDefinition("student");
????????MutablePropertyValues?propertyValues?=?bd.getPropertyValues();
????????//配置文件中的信息在加載到Spring中后以BeanDefinition的形式存在.在這里又可以更改BeanDefinition,所以可以理解為更改配置文件里面的內(nèi)容
//????????propertyValues.add("zdy","123");
????}
}
public?class?MyBeanPostProcessor?implements?BeanPostProcessor?{
????public?MyBeanPostProcessor()?{
????????super();
????????System.out.println("這是BeanPostProcessor實現(xiàn)類構(gòu)造器!!");
????}
????@Override
????public?Object?postProcessAfterInitialization(Object?arg0,?String?arg1)
????????????throws?BeansException?{
????????System.out.println("BeanPostProcessor接口方法After對屬性進(jìn)行更改!");
????????return?arg0;
????}
????@Override
????public?Object?postProcessBeforeInitialization(Object?arg0,?String?arg1)
????????????throws?BeansException?{
????????System.out.println("BeanPostProcessor接口方法Before對屬性進(jìn)行更改!");
????????return?arg0;
????}
}
public?class?MyInstantiationAwareBeanPostProcessor?extends
????????InstantiationAwareBeanPostProcessorAdapter?{
????public?MyInstantiationAwareBeanPostProcessor()?{
????????super();
????????System.out.println("這是InstantiationAwareBeanPostProcessorAdapter實現(xiàn)類構(gòu)造器?。?);
????}
????//?接口方法、實例化Bean之前調(diào)用
????@Override
????public?Object?postProcessBeforeInstantiation(Class?beanClass,
?????????????????????????????????????????????????String?beanName)?throws?BeansException?{
????????System.out.println("InstantiationAwareBeanPostProcessor調(diào)用Before方法");
????????return?null;
????}
????//?接口方法、實例化Bean之后調(diào)用
????@Override
????public?Object?postProcessAfterInitialization(Object?bean,?String?beanName)
????????????throws?BeansException?{
????????System.out.println("InstantiationAwareBeanPostProcessor調(diào)用Ater方法");
????????return?bean;
????}
????//?接口方法、設(shè)置某個屬性時調(diào)用
????@Override
????public?PropertyValues?postProcessPropertyValues(PropertyValues?pvs,
????????????????????????????????????????????????????PropertyDescriptor[]?pds,?Object?bean,?String?beanName)
????????????throws?BeansException?{
????????System.out.println("InstantiationAwareBeanPostProcessor調(diào)用postProcessPropertyValues方法");
????????return?pvs;
????}
}
public?class?App?
{
????public?static?void?main(?String[]?args?)
????{
????????ApplicationContext?ac?=new?ClassPathXmlApplicationContext("applicationContext.xml");
????????Student?stu?=?(Student)?ac.getBean("student");
????????stu.setName("wangwu");
????}
}
<beans
????<bean?id="student"?class="com.zdy.Student">
????????<constructor-arg?value="zhangsan"/>
????bean>
????<bean?id="myBeanFactoryPostProcessor"?class="com.zdy.MyBeanFactoryPostProcessor">bean>
????<bean?id="myInstantiationAwareBeanPostProcessor"?class="com.zdy.MyInstantiationAwareBeanPostProcessor">bean>
????<bean?id="myBeanPostProcessor"?class="com.zdy.MyBeanPostProcessor">bean>
beans>
這是BeanFactoryPostProcessor實現(xiàn)類構(gòu)造器??!
BeanFactoryPostProcessor調(diào)用postProcessBeanFactory方法
這是InstantiationAwareBeanPostProcessorAdapter實現(xiàn)類構(gòu)造器!!
這是BeanPostProcessor實現(xiàn)類構(gòu)造器!!
InstantiationAwareBeanPostProcessor調(diào)用Before方法
InstantiationAwareBeanPostProcessor調(diào)用postProcessPropertyValues方法
BeanNameAware......
BeanFactoryAware......
ApplicationContextAware......
BeanPostProcessor接口方法Before對屬性進(jìn)行更改!
InitializingBean......
InstantiationAwareBeanPostProcessor調(diào)用Ater方法
BeanPostProcessor接口方法After對屬性進(jìn)行更改!
上面的生命周期流程圖,時候的時候注意調(diào)用先后順序,避免屬性被覆蓋的現(xiàn)象。
BeanFactoryPostProcessor 主要是在Spring剛加載完配置文件,還沒來得及初始化Bean的時候做一些操作。比如篡改某個Bean在配置文件中配置的內(nèi)容。
InstantiationAwareBeanPostProcessorAdapter 基本沒什么鳥用,Bean初始化后,還沒有設(shè)置屬性值時調(diào)用,和BeanFactoryPostProcessor一樣,可以篡改配置文件加載到內(nèi)存中的信息。
ApplicationContextAware:用處很大,注入了ApplicationContext到Bean中。
InitializingBean:有用處,可以在Bean屬性全部改完之后,再做一些定制化操作。
BeanPostProcessor:沒什么用,Spring框架內(nèi)部使用的比較猛,像什么AOP,動態(tài)代理,都是在這搞事。后期有時間和大家分析。
其他的像什么init-method,destroy方法,基本都是個擺設(shè)。。我是沒怎么用過,只知道有這么回事。
結(jié)語
推薦閱讀:
【78期】別找了,Java集合面試問題這里幫你總結(jié)好了!
【75期】面試官:說說Redis的過期鍵刪除策略吧?。ǜ哳l)
微信掃描二維碼,關(guān)注我的公眾號
朕已閱?

