阅读源码有利于陶冶情操,承接前文Spring源码情操陶冶-AbstractApplicationContext#postProcessBeanFactory

约定:web.xml中配置的contextClassXmlWebApplicationContext

瞧瞧官方注释

  1. /**
  2. * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
  3. * respecting explicit order if given.
  4. * <p>Must be called before singleton instantiation.必须在单例实例化前调用
  5. */

主要是实例化和调用所有已注册的BeanFactoryPostProcessors beans

源码简析

对应的代码清单如下

  1. //通过一个委托类来处理实例化调用
  2. protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
  3. PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
  4. }

PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors

简单的看下委托类中的此方法源码,代码清单如下

  1. public static void invokeBeanFactoryPostProcessors(
  2. ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
  3. // 第一步,Invoke BeanDefinitionRegistryPostProcessors first, if any.
  4. Set<String> processedBeans = new HashSet<String>();
  5. //条件满足
  6. if (beanFactory instanceof BeanDefinitionRegistry) {
  7. BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
  8. List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
  9. List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
  10. new LinkedList<BeanDefinitionRegistryPostProcessor>();
  11. //刚开始进来beanFactoryPostProcessors为空
  12. for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
  13. //BeanDefinitionRegistryPostProcessor目前该接口的实现者为MapperScannerConfigurer/ConfigurationClassPostProcessor
  14. if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
  15. BeanDefinitionRegistryPostProcessor registryPostProcessor =
  16. (BeanDefinitionRegistryPostProcessor) postProcessor;
  17. //调用postProcessBeanDefinitionRegistry接口,比如MapperScannerConfigurer则会进行扫描注册接口bean操作
  18. registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
  19. registryPostProcessors.add(registryPostProcessor);
  20. }
  21. else {
  22. regularPostProcessors.add(postProcessor);
  23. }
  24. }
  25. // Do not initialize FactoryBeans here: We need to leave all regular beans
  26. // uninitialized to let the bean factory post-processors apply to them!
  27. // Separate between BeanDefinitionRegistryPostProcessors that implement
  28. // PriorityOrdered, Ordered, and the rest.
  29. //寻找实现了BeanDefinitionRegistryPostProcessor接口类的beans
  30. String[] postProcessorNames =
  31. beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
  32. // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.这里只有ConfigurationClassPostProcessor类才操作
  33. List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
  34. for (String ppName : postProcessorNames) {
  35. if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
  36. priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
  37. processedBeans.add(ppName);
  38. }
  39. }
  40. ***
  41. 省略部分代码
  42. ***
  43. // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
  44. invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
  45. invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
  46. }
  47. else {
  48. // Invoke factory processors registered with the context instance.
  49. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
  50. }
  51. //第二步,处理注册在bean工厂中BeanFactoryPostProcessor接口实现类并调用公用的方法,比如PropertyResourceConfigurer资源文件解析类
  52. String[] postProcessorNames =
  53. beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
  54. // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
  55. // Ordered, and the rest. 执行的优先权
  56. List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
  57. List<String> orderedPostProcessorNames = new ArrayList<String>();
  58. List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
  59. for (String ppName : postProcessorNames) {
  60. if (processedBeans.contains(ppName)) {
  61. // skip - already processed in first phase above
  62. }
  63. else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
  64. priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
  65. }
  66. else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
  67. orderedPostProcessorNames.add(ppName);
  68. }
  69. else {
  70. nonOrderedPostProcessorNames.add(ppName);
  71. }
  72. }
  73. ***
  74. 省略部分代码
  75. ***
  76. }

主要功能是对实现BeanFactoryPostProcessor的bean类进行调用公共接口方法postProcessBeanFactory,并相关的信息可关联至ConfigurableListableBeanFactorybeanFactory。常见的使用类为PropertyPlaceholderConfigurer文件解析类、MapperScannerConfigurer SQL接口注册类。公共接口的调用前者会对每个bean对象含有${}进行解析替换,后者会注册mapper class接口类并尝试解析注解

下节预告

Spring源码情操陶冶-AbstractApplicationContext#registerBeanPostProcessors

Spring源码情操陶冶-AbstractApplicationContext#invokeBeanFactoryPostProcessors的更多相关文章

  1. Spring源码情操陶冶-AbstractApplicationContext#registerBeanPostProcessors

    承接前文Spring源码情操陶冶-AbstractApplicationContext#invokeBeanFactoryPostProcessors 瞧瞧官方注释 /** * Instantiate ...

  2. Spring源码情操陶冶-AbstractApplicationContext#postProcessBeanFactory

    阅读源码有利于陶冶情操,承接前文Spring源码情操陶冶-AbstractApplicationContext#prepareBeanFactory 约定:web.xml中配置的contextClas ...

  3. Spring源码情操陶冶-AbstractApplicationContext#finishBeanFactoryInitialization

    承接前文Spring源码情操陶冶-AbstractApplicationContext#registerListeners 约定web.xml配置的contextClass为默认值XmlWebAppl ...

  4. Spring源码情操陶冶-AbstractApplicationContext#registerListeners

    承接前文Spring源码情操陶冶-AbstractApplicationContext#onRefresh 约定web.xml配置的contextClass为默认值XmlWebApplicationC ...

  5. Spring源码情操陶冶-AbstractApplicationContext#onRefresh

    承接前文Spring源码情操陶冶-AbstractApplicationContext#initApplicationEventMulticaster 约定web.xml配置的contextClass ...

  6. Spring源码情操陶冶-AbstractApplicationContext#initApplicationEventMulticaster

    承接前文Spring源码情操陶冶-AbstractApplicationContext#initMessageSource 约定web.xml配置的contextClass为默认值XmlWebAppl ...

  7. Spring源码情操陶冶-AbstractApplicationContext#initMessageSource

    承接前文Spring源码情操陶冶-AbstractApplicationContext#registerBeanPostProcessors 约定web.xml配置的contextClass为默认值X ...

  8. Spring源码情操陶冶-AbstractApplicationContext#prepareBeanFactory

    阅读源码有助于陶冶情操,本文承接Spring源码情操陶冶-AbstractApplicationContext#obtainFreshBeanFactory 瞧瞧官方注释 /** * Configur ...

  9. Spring源码情操陶冶-AbstractApplicationContext#obtainFreshBeanFactory

    前言-阅读源码有利于陶冶情操,本文承接前文Spring源码情操陶冶-AbstractApplicationContext 约束: 本文指定contextClass为默认的XmlWebApplicati ...

随机推荐

  1. 快速排序(Quicksort)的Javascript实现

    日本程序员norahiko,写了一个排序算法的动画演示,非常有趣. 这个周末,我就用它当做教材,好好学习了一下各种排序算法. 排序算法(Sorting algorithm)是计算机科学最古老.最基本的 ...

  2. log4j 在项目中的详细配置

    1.添加log4j 包 2.首先在src目录下添加log4j.properties文件 log4j.rootLogger=debug, stdout, R log4j.appender.stdout= ...

  3. JQuery 实现返回顶部

    1.添加html <div id="back-to-top"> <a href="javascript:;" title="返回顶部 ...

  4. python 标准库 -- glob

    glob glob.glob() import glob l = glob.glob("/root/*") # 返回列表 print l # 输出如下 ['/root/databa ...

  5. ASP.NET初始化流程分析2

    上一篇讲了从创建应用程序域到创建ISAPIRuntime实例的过程,本篇继续讲Asp.net处理第一次请求的必要的初始化过程. ISAPIRuntime分析 ISAPIRuntime在System.W ...

  6. Android 4.0以后正确的获取外部sd卡存储目录

    刚解决这个棘手的问题 找了很久,随笔记下. 网上搜索 android 获取外部sd卡存储目录 普遍都是: 1) Environment.getExternalStorageDirectory() 这个 ...

  7. C#调用TSC条码打印机打印二维码

    #region 调用TSC打印机打印 /// <summary> /// 调用TSC打印机打印 /// </summary> /// <param name=" ...

  8. XML 新手入门基础知识(复制,留着自己看)

    如果您是 XML 新手,本文将为您介绍 XML 文档的基础结构,以及创建构造良好的 XML 需要遵循的规则,包括命名约定.正确的标记嵌套.属性规则.声明和实体.您还可以从本文了解到 DTD 和 sch ...

  9. webpack教程(二)——webpack.config.js文件

    首先我们需要安装一个webpack插件html-webpack-plugin,该插件的作用是帮助我们生成创建html入口文件.执行如下命令 npm install html-webpack-plugi ...

  10. QQ信鸽推送

    闲来无事,看看腾讯的信鸽推送! 优点: 1.毕竟大腿出的东西,不会太差 2.集成快 3.推送效率高,功能强,APP后台被杀的情况下同样能接受到推送. 废话少说,直接上代码: 源代码.zip