0.調(diào)試示例
@Component
public class Jeep {
public Jeep(){
System.out.println("Jeep.....constructor........");
}
@PostConstruct
public void init(){
System.out.println("Jeep.....@PostConstruct........");
}
@PreDestroy
public void destory(){
System.out.println("Jeep.....@PreDestroy......");
}
}
實(shí)現(xiàn)后置處理器接口BeanPostProcessor的JamesBeanPostProcessor.java
@Component
public class JamesBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//返回一個(gè)的對(duì)象(傳過來的對(duì)象)
//在初始化方法調(diào)用之前進(jìn)行后置處理工作,
//什么時(shí)候調(diào)用它: init-method=init之前調(diào)用
System.out.println("postProcessBeforeInitialization...."+beanName+"..."+bean);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization...."+beanName+"..."+bean);
return bean;
}
}
1.創(chuàng)建業(yè)務(wù)類bean的流程以及后置處理器的執(zhí)行時(shí)機(jī)
創(chuàng)建業(yè)務(wù)類bean的關(guān)鍵流程如下(AbstractAutowireCapableBeanFactory.java / doCreateBean()方法):
- step1.調(diào)用Jeep()的默認(rèn)構(gòu)造函數(shù)——createBeanInstance(beanName, mbd, args)
- step2.給各種屬性賦值——populateBean(beanName, mbd, instanceWrapper)
- step3.初始化bean——initializeBean(beanName, exposedObject, mbd)
step3-1.調(diào)用invokeAwareMethods(beanName, bean)
step3-2.調(diào)用后置處理器applyBeanProcessorsBeforeInitialization
step3-3.指定的初始化方法進(jìn)行初始化
step3-4.調(diào)用后置處理器applyBeanPostProcessorsAfterInitialization - step4.銷毀bean之前棋电,調(diào)用后置處理器的方法進(jìn)行處理
step1.調(diào)用Jeep()的默認(rèn)構(gòu)造函數(shù)——createBeanInstance(beanName, mbd, args)
獲取到Jeep的默認(rèn)構(gòu)造函數(shù)茎截,然后調(diào)用該默認(rèn)構(gòu)造函數(shù),創(chuàng)建Jeep的實(shí)例對(duì)象赶盔。
-
調(diào)用棧如下:
-
調(diào)用結(jié)果:
step2.給各種屬性賦值——populateBean(beanName, mbd, instanceWrapper)
Jeep沒有對(duì)各屬性進(jìn)行賦值企锌,因此,這里沒有進(jìn)行處理于未。
step3.初始化bean——initializeBean(beanName, exposedObject, mbd)
step3-1.調(diào)用invokeAwareMethods(beanName, bean)
Jeep這一步?jīng)]有任何操作撕攒。
step3-2.調(diào)用后置處理器applyBeanProcessorsBeforeInitialization
后置處理器的個(gè)數(shù),處理順序烘浦,也是按照如下的列表順序進(jìn)行逐個(gè)處理的:
這里有兩個(gè)后置處理器進(jìn)行處理:
1)JamesBeanPostProcessor
-
調(diào)用棧
-
調(diào)用結(jié)果:
2)InitDestroyAnnotationBeanPostProcessor對(duì)@PostConstruct的處理
InitDestroyAnnotationBeanPostProcessor是使用CommonAnnotationBeanPostProcessor進(jìn)行調(diào)用的抖坪。
public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable
-
調(diào)用棧
-
調(diào)用結(jié)果:
step3-3.指定的初始化方法進(jìn)行初始化
Jeep沒有指定初始化方法。
step3-4.調(diào)用后置處理器applyBeanPostProcessorsAfterInitialization
這里只有1個(gè)后置處理器進(jìn)行處理:
1)JamesBeanPostProcessor
-
調(diào)用棧:
-
調(diào)用結(jié)果:
step4.銷毀bean之前闷叉,調(diào)用后置處理器的方法進(jìn)行處理
這里只有1個(gè)后置處理器進(jìn)行處理:
1)InitDestroyAnnotationBeanPostProcessor對(duì)@PreDestroy的處理
-
調(diào)用棧:
-
調(diào)用結(jié)果:
2.后置處理器的創(chuàng)建流程
2.1 CommonAnnotationBeanPostProcessor的創(chuàng)建
-
該后置處理器創(chuàng)建的調(diào)用棧
其getBean()與業(yè)務(wù)getBean()是一模一樣的擦俐。
2.2 JamesBeanPostProcessor的穿件
-
調(diào)用棧(同上,都是調(diào)用getBean()創(chuàng)建)
其他說明
1)priorityOrderedPostProcessors握侧,orderedPostProcessors和nonOrderedPostProcessors
三種排序類型的后置處理器捌肴,先處理priorityOrderedPostProcessors,最后處理nonOrderedPostProcessors藕咏;
加入ConfigurableListableBeanFactory beanFactory的beanPostProcessors是按順序依次加入到末尾位置。
3.總結(jié)
參考
- 1)享學(xué)課堂James老師筆記