Spring的BeanFactoryPostProcessor接口示例代码详解
接口简介
BeanFactoryPostProcessor接口是Spring初始化BeanFactory时对外暴露的扩展点,SpringIoC容器允许BeanFactoryPostProcessor在容器实例化任何bean之前读取bean的定义,并可以修改它。
BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProcessor,比BeanFactoryPostProcessor具有更高的优先级,主要用来在常规的BeanFactoryPostProcessor检测开始之前注册其他bean定义。特别是,你可以通过BeanDefinitionRegistryPostProcessor来注册一些常规的BeanFactoryPostProcessor,因为此时所有常规的BeanFactoryPostProcessor都还没开始被处理。
注意点:通过BeanDefinitionRegistryPostProcessor注册的BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法将得不到调用,具体的原因会在下面的代码中解释。
BeanFactoryPostProcessor接口调用机制
BeanFactoryPostProcessor接口的调用在AbstractApplicationContext#invokeBeanFactoryPostProcessors方法中。
protectedvoidinvokeBeanFactoryPostProcessors(ConfigurableListableBeanFactorybeanFactory){ PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory,getBeanFactoryPostProcessors()); //DetectaLoadTimeWeaverandprepareforweaving,iffoundinthemeantime //(e.g.throughan@BeanmethodregisteredbyConfigurationClassPostProcessor) if(beanFactory.getTempClassLoader()==null&&beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)){ beanFactory.addBeanPostProcessor(newLoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(newContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }
进入PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory,getBeanFactoryPostProcessors())方法:
publicstaticvoidinvokeBeanFactoryPostProcessors( ConfigurableListableBeanFactorybeanFactory,ListbeanFactoryPostProcessors){ //用于存放已经处理过的Bean名字 Set processedBeans=newHashSet<>(); //一般会进入这个判断 if(beanFactoryinstanceofBeanDefinitionRegistry){ BeanDefinitionRegistryregistry=(BeanDefinitionRegistry)beanFactory; //所谓的regularPostProcessors就是指实现BeanFactoryPostProcessor接口的Bean List regularPostProcessors=newArrayList<>(); //所谓的registryProcessors就是指实现BeanDefinitionRegistryPostProcessor接口的Bean List registryProcessors=newArrayList<>(); //这边遍历的是通过ApplicationContext接口注册的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor接口 //需要和BeanFactory中BeanDefinitionMap中的BeanFactoryPostProcessor接口区分开 for(BeanFactoryPostProcessorpostProcessor:beanFactoryPostProcessors){ if(postProcessorinstanceofBeanDefinitionRegistryPostProcessor){ BeanDefinitionRegistryPostProcessorregistryProcessor= (BeanDefinitionRegistryPostProcessor)postProcessor; //如果是BeanDefinitionRegistryPostProcessor,则先进行postProcessBeanDefinitionRegistry处理,这个方法一般进行BeanDefinition注册,从这边可以看出BeanDefinitionRegistryPostProcessor接口的方法先调用,所以优先级高于BeanFactoryPostProcessor //通过这个代码可以看出,通过ApplicationContext直接注册的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor并不支持Order接口,而是根据注册的顺序执行 registryProcessor.postProcessBeanDefinitionRegistry(registry); //保存这个BeanDefinitionRegistryPostProcessor,因为还要执行这个类的BeanFactoryPostProcessor方法; registryProcessors.add(registryProcessor); } else{ //保存,后面还要执行这个类的BeanFactoryPostProcessor方法; regularPostProcessors.add(postProcessor); } } List currentRegistryProcessors=newArrayList<>(); //这边获取的是BeanFactory中的BeanDefinitionRegistryPostProcessor String[]postProcessorNames= beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class,true,false); for(StringppName:postProcessorNames){ //先处理PriorityOrdered标注的BeanDefinitionRegistryPostProcessor if(beanFactory.isTypeMatch(ppName,PriorityOrdered.class)){ currentRegistryProcessors.add(beanFactory.getBean(ppName,BeanDefinitionRegistryPostProcessor.class)); //将其标记为已经处理,防止重复处理 processedBeans.add(ppName); } } //将其排序,以便按顺序处理 sortPostProcessors(currentRegistryProcessors,beanFactory); //将其保存,以便处理这个类的BeanFactoryPostProcessor方法 registryProcessors.addAll(currentRegistryProcessors); //执行BeanDefinitionRegistryPostProcessor接口方法 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors,registry); //清除,以便开始处理@Order标注的注解 currentRegistryProcessors.clear(); //注意:这边重新获取BeanDefinitionRegistryPostProcessor是有深意的,因为上面在处理@PriorityOrdered标注的BeanDefinitionRegistryPostProcessor时可能又注入了新的BeanDefinitionRegistryPostProcessor。 postProcessorNames=beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class,true,false); for(StringppName:postProcessorNames){ //判断是否处理过,防止重复处理,下面的逻辑和上面相同,不介绍了 if(!processedBeans.contains(ppName)&&beanFactory.isTypeMatch(ppName,Ordered.class)){ currentRegistryProcessors.add(beanFactory.getBean(ppName,BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors,beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors,registry); currentRegistryProcessors.clear(); //处理不标注注解的BeanDefinitionRegistryPostProcessor booleanreiterate=true; while(reiterate){ reiterate=false; postProcessorNames=beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class,true,false); for(StringppName:postProcessorNames){ if(!processedBeans.contains(ppName)){ currentRegistryProcessors.add(beanFactory.getBean(ppName,BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); reiterate=true; } } sortPostProcessors(currentRegistryProcessors,beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors,registry); currentRegistryProcessors.clear(); } //调用postProcessBeanFactory方法,所以BeanDefinitionRegistryPostProcessor中的postProcessBeanFactory方法的优先级要高。 invokeBeanFactoryPostProcessors(registryProcessors,beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors,beanFactory); } else{ //Invokefactoryprocessorsregisteredwiththecontextinstance. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors,beanFactory); } //开始处理BeanFactoryPostProcessor接口 String[]postProcessorNames= beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class,true,false); //也是按照@PriorityOrdered@Ordered和普通的方式进行处理 List priorityOrderedPostProcessors=newArrayList<>(); List orderedPostProcessorNames=newArrayList<>(); List nonOrderedPostProcessorNames=newArrayList<>(); for(StringppName:postProcessorNames){ //可能已经处理过 if(processedBeans.contains(ppName)){ //skip-alreadyprocessedinfirstphaseabove } elseif(beanFactory.isTypeMatch(ppName,PriorityOrdered.class)){ priorityOrderedPostProcessors.add(beanFactory.getBean(ppName,BeanFactoryPostProcessor.class)); } elseif(beanFactory.isTypeMatch(ppName,Ordered.class)){ orderedPostProcessorNames.add(ppName); } else{ nonOrderedPostProcessorNames.add(ppName); } } //先执行@PriorityOrdered标注的接口 sortPostProcessors(priorityOrderedPostProcessors,beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors,beanFactory); //处理@Order标注的类 List orderedPostProcessors=newArrayList<>(orderedPostProcessorNames.size()); for(StringpostProcessorName:orderedPostProcessorNames){ //这边通过名字重新拿了Bean,应该是怕上面的处理改变了Bean orderedPostProcessors.add(beanFactory.getBean(postProcessorName,BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors,beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors,beanFactory); //最后调用普通的BeanFactoryPostProcessor List nonOrderedPostProcessors=newArrayList<>(nonOrderedPostProcessorNames.size()); for(StringpostProcessorName:nonOrderedPostProcessorNames){ nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName,BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors,beanFactory); //Clearcachedmergedbeandefinitionssincethepost-processorsmighthave //modifiedtheoriginalmetadata,e.g.replacingplaceholdersinvalues... beanFactory.clearMetadataCache(); }
简单总结
上面的方法看起来很长很复杂,但其实干的事情并不多,就调用了BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor接口的实现。这边再简单总结下具体的过程:
step1:执行通过ApplicationContext#addBeanFactoryPostProcessor()方法注册的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor。
具体过程如下:假如通过ApplicationContext注册了一个BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor,那么会先执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法,但是BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法和BeanFactoryPostProcessor的postProcessBeanFactory方法暂时都不会在这步执行。
另外需要注意的是:通过ApplicationContext注册的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor都不支持@PriorityOrdered和@Ordered顺序处理,而是按照我们添加的顺序处理
step2:处理BeanFactory中的BeanDefinitionRegistryPostProcessor,处理的顺序是先处理@PriorityOrdered标注的,再处理@Ordered标注的,最后处理普通的BeanDefinitionRegistryPostProcessor。到这边,所有BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法都已经调用完毕,下面就开始处理BeanFactoryPostProcessor的postProcessBeanFactory方法。
step3:调用BeanDefinitionRegistryPostProcessor实现的postProcessBeanFactory方法(因为BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口)
step4:调用通过ApplicationContext#addBeanFactoryPostProcessor()注册的“单纯”的BeanFactoryPostProcessor
step5:调用BeanFactory中的BeanFactoryPostProcessor,调用顺序也是按照@PriorityOrdered和@Ordered顺序处理,没有这两个注解的最后处理。
好了,到这边BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor接口就已经处理完了。后面我们会拿ConfigurationClassPostProcessor这个特殊的BeanDefinitionRegistryPostProcessor做列子讲下具体流程,这边只是介绍BeanFactoryPostProcessor的调用机制。
到此这篇关于Spring的BeanFactoryPostProcessor接口的文章就介绍到这了,更多相关SpringBeanFactoryPostProcessor接口内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。