spring源码学习笔记-初始化(四)-PostProcessor

转自http://www.sandzhang.com/blog/2011/04/05/spring-study-notes-initialization-4/

refresh()方法中在上篇看到了postProcessBeanFactory(beanFactory),这篇继续往下看。

注:refresh()的代码就不再次列举了,请看spring源码中AbstractApplicationContext类。

一、invokeBeanFactoryPostProcessors(beanFactory),这个方法从名字就可以看出是在调用BeanFactoryProcessor,代码也比较长,分成几部分来看。

第1部分:


Set<String> processedBeans = new HashSet<String>();
if (beanFactory instanceof BeanDefinitionRegistry) {
    BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
    List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
    List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
            new LinkedList<BeanDefinitionRegistryPostProcessor>();
    for (BeanFactoryPostProcessor postProcessor : getBeanFactoryPostProcessors()) {
        if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
            BeanDefinitionRegistryPostProcessor registryPostProcessor =
                    (BeanDefinitionRegistryPostProcessor) postProcessor;
            registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
            registryPostProcessors.add(registryPostProcessor);
        }
        else {
            regularPostProcessors.add(postProcessor);
        }
    }
    Map<String, BeanDefinitionRegistryPostProcessor> beanMap =
            beanFactory.getBeansOfType(BeanDefinitionRegistryPostProcessor.class, true, false);
    List<BeanDefinitionRegistryPostProcessor> registryPostProcessorBeans =
            new ArrayList<BeanDefinitionRegistryPostProcessor>(beanMap.values());
    OrderComparator.sort(registryPostProcessorBeans);
    for (BeanDefinitionRegistryPostProcessor postProcessor : registryPostProcessorBeans) {
        postProcessor.postProcessBeanDefinitionRegistry(registry);
    }
    invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(registryPostProcessorBeans, beanFactory);
    invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    processedBeans.addAll(beanMap.keySet());
}
else {
    invokeBeanFactoryPostProcessors(getBeanFactoryPostProcessors(), beanFactory);
}

  • 首先创建一个HashSet变量processedBeans,接着是个判断,如果beanFactory类型实现了BeanDefinitionRegistry接口,强转beanFactory对象为BeanDefinitionRegistry类型变量registry,创建两个LinkedList变量regularPostProcessors用来存储普通PostProcessor;registryPostProcessors用来存储一些用来对bean定义的注册信息进行处理的PostProcessor。
  • 7-17行循环所有applicationContext中已经注册的BeanFactoryPostProcessor,如果是实现了BeanDefinitionRegistryPostProcessor的类型,则调用对应的postProcessBeanDefinitionRegistry()方法进行相应处理并加入到registryPostProcessors中,否则加入到regularPostProcessors中。
  • 18-25行首先调用BeanFactory的getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)方法获取所有类型为BeanDefinitionRegistryPostProcessor的bean,然后放到List对象registryPostProcessorBeans中并且进行排序,排序之后循环调用每个bean的postProcessBeanDefinitionRegistry()方法。
    注:getBeansOfType()后续会有一个针对beanFactory的专门研究先不做详细分析,这里简单说一下排序,spring内部实现了一套排序方法,主要是一个Ordered接口,需要排序的对象实现这个接口的getOrder()方法,在进行排序的时候会对这个结果进行比较从而实现排序。另外假如某个对象实现的是PriorityOrdered接口则优先进行排序,同样情况则依旧比较getOrder()的结果。
  • 26-28行依次对3个List对象调用invokeBeanFactoryPostProcessors()方法,进行BeanFactoryPostProcessor的处理,顺序为registryPostProcessors、registryPostProcessorBeans、regularPostProcessors。invokeBeanFactoryPostProcessors()方法的代码很简单,就是for循环调用每个postProcessor对象的postProcessBeanFactory(beanFactory)方法。
  • 29行把所有bean中加载过来的BeanDefinitionRegistryPostProcessor类型的bean的名字加入到processedBeans中。
  • 回到上面最开始的判断,如果beanFactory类型没有实现BeanDefinitionRegistry接口,则直接调用invokeBeanFactoryPostProcessors()方法处理所有ApplicationContext已注册的BeanFactoryPostProcessor。

第2部分:

String[] postProcessorNames =
        beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
    if (processedBeans.contains(ppName)) {
        // skip - already processed in first phase above
    }
    else if (isTypeMatch(ppName, PriorityOrdered.class)) {
        priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
    }
    else if (isTypeMatch(ppName, Ordered.class)) {
        orderedPostProcessorNames.add(ppName);
    }
    else {
        nonOrderedPostProcessorNames.add(ppName);
    }
}
OrderComparator.sort(priorityOrderedPostProcessors);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
 
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : orderedPostProcessorNames) {
    orderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
OrderComparator.sort(orderedPostProcessors);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
 
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
    nonOrderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

  • 第1、2行首先获取所有类型为BeanFactoryPostProcessor的bean的name集合放到变量postProcessorNames
  • 第3行建立一个ArrayList变量priorityOrderedPostProcessors用来存储需优先处理的postProcessor
  • 第4、5行分别建立两个ArrayList变量orderedPostProcessorNames、nonOrderedPostProcessorNames用来存储有排序的和无排序的postProcessor
  • 第6-19行循环上面获取到的所有postProcessor的name集合,按条件进行不同处理:
        如果name已经存在于processedBeans则代表是已经处理过了,跳过这一个;
        调用isTypeMatch()方法根据bean的name判断该bean是否实现了PriorityOrdered接口(上面我们说过排序中这个属于优先排序),如果是的话根据该name取出对应的bean对象加入到priorityOrderedPostProcessors集合中;
        调用isTypeMatch()方法根据bean的name判断该bean是否实现了Ordered接口(上面我们说过实现了这个接口就可以进行排序了),如果是的话把该name加入到orderedPostProcessorNames集合中;
        如果都上面条件都不成立,则加入到nonOrderedPostProcessorNames集合中;
    注:关于isTypeMatch()方法,说起来简单就是根据bean的name取出bean对象然后进行类型判断,但实际上这个方法并不简单,最终主逻辑代码在AbstractBeanFactory中,做个标记,以后单独抽出来分析一下。
  • 第20行对priorityOrderedPostProcessors进行排序
  • 第21行调用invokeBeanFactoryPostProcessors()方法对priorityOrderedPostProcessors中的所有postProcessor进行处理
  • 第23-28行通过getBean()方法取得所有orderedPostProcessorNames集合中postProcessor的bean对象,然后加入到一个新的集合变量orderedPostProcessors中,然后对这个集合排序,最后调用invokeBeanFactoryPostProcessors()方法处理
  • 后面的一部分是对无排序的nonOrderedPostProcessorNames进行处理,除了去掉排序步骤之外和上面的步骤一样,就不重复描述了

二、我们回到refresh()方法中,看下一行:registerBeanPostProcessors(beanFactory),这个方法主要就是对BeanPostProcessor的注册,依旧分为几部分来看:

第1部分:

String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

  • 第1行获取所有的BeanPostProcessor类型的bean的name数组
  • 第2行计算BeanPostProcessor的数量:banFactory中已注册的BeanPostProcessor的数量 + 1 + 上面获取到的所有bean中的BeanPostProcessor的数量。这里面的那个+1,是下一行的BeanPostProcessorChecker
  • 第3行注册一个BeanPostProcessorChecker到beanFactory中,这个BeanPostProcessor作用是当一个bean创建后没有被所有的BeanPostProcessor处理的时候打印一行info级别日志

第2部分:

List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
    if (isTypeMatch(ppName, PriorityOrdered.class)) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        priorityOrderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    else if (isTypeMatch(ppName, Ordered.class)) {
        orderedPostProcessorNames.add(ppName);
    }
    else {
        nonOrderedPostProcessorNames.add(ppName);
    }
}

  • 这部分代码与BeanFactoryPostProcessor的处理那部分类似,就是把所有的BeanPostProcessor进行区分放到不同集合里,优先的、排序的、无排序的。有个特殊的地方就是多了一个internalPostProcessors集合,用来存放优先级别中类型为MergedBeanDefinitionPostProcessor的BeanPostProcessor。它的主要作用是在spring运行时合并处理bean定义,例如注解中的bean定义,这部分也还没完全弄清楚,做个标记,回头专项分析。

第3部分:


OrderComparator.sort(priorityOrderedPostProcessors);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
 
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : orderedPostProcessorNames) {
    BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
    orderedPostProcessors.add(pp);
    if (pp instanceof MergedBeanDefinitionPostProcessor) {
        internalPostProcessors.add(pp);
    }
}
OrderComparator.sort(orderedPostProcessors);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
 
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : nonOrderedPostProcessorNames) {
    BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
    nonOrderedPostProcessors.add(pp);
    if (pp instanceof MergedBeanDefinitionPostProcessor) {
        internalPostProcessors.add(pp);
    }
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
 
OrderComparator.sort(internalPostProcessors);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
 
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector());

  • 第1-2行对priorityOrderedPostProcessors进行排序,并调用registerBeanPostProcessors()方法进行注册处理,这个方法内部代码比较简单,就是循环这个集合并调用beanFactory.addBeanPostProcessor(postProcessor)把每个BeanPostProcessor注册到beanFactory。
  • 第3-13行和之前也类似了,把所有orderedPostProcessorNames中的BeanPostProcessor取出来放到集合里,其中MergedBeanDefinitionPostProcessor类型的依旧加入到internalPostProcessors中。最后两行先排序,再调用registerBeanPostProcessors()方法进行注册处理
  • 第14-23行是对nonOrderedPostProcessorNames的处理,相比上面去掉了排序过程,其他依旧。
  • 紧接着的是对internalPostProcessors排序,注册处理。
  • 最后一行注册了一个BeanPostProcessor:ApplicationListenerDetector,这个是AbstractApplicationContext的内部类,实现了MergedBeanDefinitionPostProcessor接口,这个类只是暂时知道是在处理ApplicationListener相关的东西,具体作用还未知,留待分析。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值