javascript
Spring系列之BeanPostProcessor分析
在Spring系列之Bean的生命周期及相關(guān)源碼中,我們最后簡(jiǎn)單使用過(guò)BeanPostProcessor,這次我們就結(jié)合源碼來(lái)具體談?wù)勥@個(gè)BeanPostProcessor的作用。
實(shí)現(xiàn)BeanPostProcessor接口的類(lèi)
public class TestBeanPostProcessor implements BeanPostProcessor {@Nullable@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("postProcessBeforeInitialization——"+beanName+"——"+bean);return bean;}@Nullable@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("postProcessAfterInitialization————"+beanName+"——"+bean);return bean;} }然后我們看一下測(cè)試類(lèi)
public class TestMain {@Testpublic void test(){AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(TestConfig.class);} }我們可以看到除了我們自定義的Dog類(lèi)被我們自定義的后置處理器TestBeanPostProcessor 增強(qiáng)了之外,還有幾個(gè)默認(rèn)的Bean也被增強(qiáng)了,那Spring容器中還有沒(méi)有被我們自定義的后置處理器增強(qiáng)的Bean么,我們可以看一下Spring共有多個(gè)Bean存在。
控制bean的兩種擴(kuò)展方式
兩種方式可以對(duì)bean做控制(例如修改某個(gè)成員變量)
1. 改變bean的定義(BeanFactoryPostProcessor接口) ,可以想象成修改了class文件,這樣實(shí)例化出來(lái)的每個(gè)對(duì)象都變了;
2. 只改變實(shí)例化的對(duì)象(BeanPostProcessor接口);
源碼分析:BeanPostProcessor接口的實(shí)現(xiàn)類(lèi)如何被注冊(cè)到spring容器
1. 從spring容器的初始化代碼看起吧,看AbstractApplicationContext類(lèi)的refresh方法,如下圖所示,紅框中的方法負(fù)責(zé)將BeanPostProcessor接口的實(shí)現(xiàn)類(lèi)注冊(cè)到spring容器:
2.?展開(kāi)registerBeanPostProcessors方法,發(fā)現(xiàn)是委托PostProcessorRegistrationDelegate類(lèi)的靜態(tài)方法registerBeanPostProcessors來(lái)完成注冊(cè)工作的:
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); }3. 展開(kāi)PostProcessorRegistrationDelegate.registerBeanPostProcessors方法,里面的代碼邏輯簡(jiǎn)潔整齊,意圖目的一目了然:
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {//獲取所有實(shí)現(xiàn)BeanPostProcessor接口的bean的名稱(chēng)String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);//注意,此時(shí)盡管注冊(cè)操作還沒(méi)有開(kāi)始,但是之前已經(jīng)有一些特殊的bean已經(jīng)注冊(cè)進(jìn)來(lái)了,//詳情請(qǐng)看AbstractApplicationContext類(lèi)的prepareBeanFactory方法,//因此getBeanPostProcessorCount()方法返回的數(shù)量并不為零,//加一是因?yàn)榉椒┪矔?huì)注冊(cè)一個(gè)ApplicationListenerDetector接口的實(shí)現(xiàn)類(lèi)int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;//這里的BeanPostProcessorChecker也是個(gè)BeanPostProcessor的實(shí)現(xiàn)類(lèi),用于每個(gè)bean的初始化完成后,做一些簡(jiǎn)單的檢查beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));//如果這些bean還實(shí)現(xiàn)了PriorityOrdered接口(在意執(zhí)行順序),就全部放入集合priorityOrderedPostProcessors List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();//集合internalPostProcessors,用來(lái)存放同時(shí)實(shí)現(xiàn)了PriorityOrdered和MergedBeanDefinitionPostProcessor接口的beanList<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();//集合orderedPostProcessorNames用來(lái)存放實(shí)現(xiàn)了Ordered接口的bean的名稱(chēng)(在意執(zhí)行順序)List<String> orderedPostProcessorNames = new ArrayList<String>();//集合nonOrderedPostProcessorNames用來(lái)存放即沒(méi)實(shí)現(xiàn)PriorityOrdered接口,也沒(méi)有實(shí)現(xiàn)Ordered接口的bean的名稱(chēng)(不關(guān)心執(zhí)行順序)List<String> nonOrderedPostProcessorNames = new ArrayList<String>();for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);//實(shí)現(xiàn)了PriorityOrdered接口的bean,都放入集合priorityOrderedPostProcessorspriorityOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {//實(shí)現(xiàn)了MergedBeanDefinitionPostProcessor接口的bean,都放入internalPostProcessors集合internalPostProcessors.add(pp);}}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {//實(shí)現(xiàn)了Ordered接口的bean,將其名稱(chēng)都放入orderedPostProcessorNames集合orderedPostProcessorNames.add(ppName);}else {//既沒(méi)實(shí)現(xiàn)PriorityOrdered接口,也沒(méi)有實(shí)現(xiàn)Ordered接口的bean,將其名稱(chēng)放入nonOrderedPostProcessorNames集合nonOrderedPostProcessorNames.add(ppName);}}//實(shí)現(xiàn)了PriorityOrdered接口的bean排序OrderComparator.sort(priorityOrderedPostProcessors);//注冊(cè)到容器registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();//處理所有實(shí)現(xiàn)了Ordered接口的beanfor (String ppName : orderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);orderedPostProcessors.add(pp);//前面將所有實(shí)現(xiàn)了PriorityOrdered和MergedBeanDefinitionPostProcessor的bean放入internalPostProcessors,//此處將所有實(shí)現(xiàn)了Ordered和MergedBeanDefinitionPostProcessor的bean放入internalPostProcessorsif (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}//實(shí)現(xiàn)了Ordered接口的bean排序OrderComparator.sort(orderedPostProcessors);//注冊(cè)到容器registerBeanPostProcessors(beanFactory, orderedPostProcessors);List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();for (String ppName : nonOrderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);nonOrderedPostProcessors.add(pp);//此處將其余實(shí)現(xiàn)了MergedBeanDefinitionPostProcessor的bean放入internalPostProcessorsif (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}//注冊(cè)到容器registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);OrderComparator.sort(internalPostProcessors);//將所有實(shí)現(xiàn)了MergedBeanDefinitionPostProcessor接口的bean也注冊(cè)到容器registerBeanPostProcessors(beanFactory, internalPostProcessors);//創(chuàng)建一個(gè)ApplicationListenerDetector對(duì)象并且注冊(cè)到容器,這就是前面計(jì)算beanProcessorTargetCount的值時(shí)加一的原因beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); }以上代碼已加注釋,就不多解讀了,有一點(diǎn)需要注意:對(duì)于實(shí)現(xiàn)了MergedBeanDefinitionPostProcessor接口的bean,在前面幾次調(diào)用registerBeanPostProcessors方法的時(shí)候已經(jīng)注冊(cè)過(guò)了,那么在最后執(zhí)行的registerBeanPostProcessors(beanFactory, internalPostProcessors),豈不是將一個(gè)bean注冊(cè)了多次?
為了弄清楚這個(gè)問(wèn)題需要看registerBeanPostProcessors方法:
private static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {for (BeanPostProcessor postProcessor : postProcessors) {//對(duì)每個(gè)bean都調(diào)用beanFactory.addBeanPostProcessor方法來(lái)注冊(cè)beanFactory.addBeanPostProcessor(postProcessor);} }addBeanPostProcessor方法的代碼在AbstractApplicationContext類(lèi)中,如下所示,先刪除再添加,這樣反復(fù)注冊(cè)也沒(méi)有問(wèn)題:
@Override public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");//如果已經(jīng)注冊(cè),就先刪除掉this.beanPostProcessors.remove(beanPostProcessor);//再注冊(cè)this.beanPostProcessors.add(beanPostProcessor);if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {this.hasInstantiationAwareBeanPostProcessors = true;}if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {this.hasDestructionAwareBeanPostProcessors = true;} }至此,我們已經(jīng)弄清楚了BeanPostProcessor實(shí)現(xiàn)類(lèi)的bean注冊(cè)到spring容器的邏輯,接下來(lái)看看spring容器如何使用這些bean;
源碼分析,BeanPostProcessor實(shí)現(xiàn)類(lèi)如何被使用
1.?要弄清楚BeanPostProcessor接口的實(shí)現(xiàn)類(lèi)是在哪里被用到的,還是從負(fù)責(zé)容器初始化的AbstractApplicationContext類(lèi)的refresh方法看起,如下圖紅框中的finishBeanFactoryInitialization方法,就是負(fù)責(zé)實(shí)例化和初始化bean的:
2.?從finishBeanFactoryInitialization方法到BeanPostProcessor的實(shí)現(xiàn)類(lèi)被使用,中間有多層邏輯和調(diào)用,篇幅所限就不逐個(gè)展開(kāi)了,直接列出堆棧信息,您可以根據(jù)此信息去查看對(duì)應(yīng)源碼:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean() org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean() org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean() org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject() org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton() org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean() org.springframework.beans.factory.support.AbstractBeanFactory.getBean() org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons() org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization() org.springframework.context.support.AbstractApplicationContext.refresh() org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh() org.springframework.boot.SpringApplication.refresh() org.springframework.boot.SpringApplication.refreshContext() org.springframework.boot.SpringApplication.run() org.springframework.boot.SpringApplication.run() org.springframework.boot.SpringApplication.run()3. 根據(jù)上述堆棧信息,直接查看AbstractAutowireCapableBeanFactory類(lèi)的initializeBean()方法:
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {if (System.getSecurityManager() != null) {AccessController.doPrivileged(new PrivilegedAction<Object>() {@Overridepublic Object run() {invokeAwareMethods(beanName, bean);return null;}}, getAccessControlContext());}else {invokeAwareMethods(beanName, bean);}Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {//對(duì)已經(jīng)實(shí)例化的bean,在初始化前用BeanPostProcessor實(shí)現(xiàn)類(lèi)去處理wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {//bean的初始化invokeInitMethods(beanName, wrappedBean, mbd);}catch (Throwable ex) {throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),beanName, "Invocation of init method failed", ex);}if (mbd == null || !mbd.isSynthetic()) {//對(duì)已經(jīng)實(shí)例化的bean,在初始化后用BeanPostProcessor實(shí)現(xiàn)類(lèi)去處理wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean; }如上所示,我們最關(guān)注的代碼是applyBeanPostProcessorsBeforeInitialization和applyBeanPostProcessorsAfterInitialization這兩個(gè)方法,它們分別在bean的初始化方法invokeInitMethods的前后被執(zhí)行;
4. 先看看applyBeanPostProcessorsBeforeInitialization方法,邏輯非常簡(jiǎn)單,就是取出所有已注冊(cè)的BeanPostProcessor實(shí)現(xiàn)類(lèi),執(zhí)行其postProcessBeforeInitialization方法,入?yún)⑹钱?dāng)前正在做實(shí)例化和初始化的bean實(shí)例:
@Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;//逐一執(zhí)行每個(gè)BeanPostProcessor實(shí)現(xiàn)類(lèi)的postProcessBeforeInitialization方法for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {result = beanProcessor.postProcessBeforeInitialization(result, beanName);if (result == null) {return result;}}return result; }5. 在invokeInitMethods方法執(zhí)行完畢后會(huì)執(zhí)行applyBeanPostProcessorsAfterInitialization方法,代碼如下,與applyBeanPostProcessorsBeforeInitialization如出一轍,僅有的不同是調(diào)用的beanProcessor的方法變成了postProcessAfterInitialization:
@Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;//逐一執(zhí)行每個(gè)BeanPostProcessor實(shí)現(xiàn)類(lèi)的postProcessAfterInitialization方法for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {result = beanProcessor.postProcessAfterInitialization(result, beanName);if (result == null) {return result;}}return result; }以上就是spring容器初始化過(guò)程中對(duì)BeanPostProcessor實(shí)現(xiàn)類(lèi)的使用場(chǎng)景,此時(shí)還剩一點(diǎn)疑問(wèn)需要澄清:在分析注冊(cè)過(guò)程的時(shí)候,曾看到實(shí)現(xiàn)MergedBeanDefinitionPostProcessor接口的bean是最后注冊(cè)的,那么這些MergedBeanDefinitionPostProcessor實(shí)現(xiàn)類(lèi)在spring容器中是何處使用的呢?
為了搞清這個(gè)問(wèn)題,來(lái)看看AbstractAutowireCapableBeanFactory類(lèi)的doCreateBean方法,前面我們分析的initializeBean方法就是在這里面被調(diào)用的:
如上圖所示,紅框中就是用所有MergedBeanDefinitionPostProcessor實(shí)現(xiàn)類(lèi)去處理當(dāng)前正在實(shí)例化的bean,然后才會(huì)執(zhí)行綠框中的initializeBean方法(里面是我們剛才分析的bean的初始化,BeanPostProcessor實(shí)現(xiàn)類(lèi)被使用的邏輯);
來(lái)看看紅框中的applyMergedBeanDefinitionPostProcessors方法,主要目的是處理特殊的合成bean的定義類(lèi):
至此,我們對(duì)BeanPostProcessor有關(guān)的源碼分析就完成了,小結(jié)一下:
1. 初始化時(shí),spring容器有特別處理,會(huì)直接調(diào)用beanFactory.addBeanPostProcessor進(jìn)行注冊(cè)(例如AbstractApplicationContext類(lèi)的prepareBeanFactory方法中就有);
2. 找出所有實(shí)現(xiàn)了BeanPostProcessor接口的bean,注冊(cè)到容器,注冊(cè)順序如下:
第一:實(shí)現(xiàn)了PriorityOrdered接口的,排序后;
第二:實(shí)現(xiàn)了Ordered接口的,排序后;
第三:既沒(méi)實(shí)現(xiàn)PriorityOrdered接口,也沒(méi)有實(shí)現(xiàn)Ordered接口的;
第四:實(shí)現(xiàn)了MergedBeanDefinitionPostProcessor接口的(這些也按照PriorityOrdered、Ordered等邏輯拍過(guò)續(xù));
第五:實(shí)例化一個(gè)ApplicationListenerDetector對(duì)象;
3. 實(shí)例化bean的時(shí)候,對(duì)于每個(gè)bean,先用MergedBeanDefinitionPostProcessor實(shí)現(xiàn)類(lèi)的postProcessMergedBeanDefinition方法處理每個(gè)bean的定義類(lèi);
4. 再用BeanPostProcessor的postProcessBeforeInitialization方法處理每個(gè)bean實(shí)例;
5. bean實(shí)例初始化;
6. 用BeanPostProcessor的postProcessAfterInitialization方法處理每個(gè)bean實(shí)例;
源碼分析結(jié)束,接下來(lái)自定義一個(gè)BeanPostProcessor實(shí)現(xiàn)類(lèi),驗(yàn)證我們之前的分析:控制bean實(shí)例;
?
總結(jié)
以上是生活随笔為你收集整理的Spring系列之BeanPostProcessor分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: AnnotationConfigAppl
- 下一篇: Aware接口