Spring容器启动(下)

导读:本篇文章讲解 Spring容器启动(下),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

PostProcessors扫描与实例化

《Spring容器启动(中)》的文章中,介绍了Spring容器在启动时,调用refresh()方法进行各种初始化和实例化,而其中最重要的就是BeanFactoryPostProcessor扫描、实例化、执行以及BeanPostProcessor的初始化和实例化

这边文章将重点介绍refresh()中的核心方法invokeBeanFactoryPostProcessors(beanFactory)和registerBeanPostProcessors(beanFactory);

BeanFactoryPostProcessor和BeanPostProcessor的主要区别在于前者用于BeanFactory实例的修改以及一些配置类的扫描等工作,而后者主要用于Bean实例化的过程的属性注入、初始化等操作

一、 扫描BeanFactoryPostProcessor并执行方法

通过调用PostProcessorRegistrationDelegate类的invokeBeanFactoryPostProcessors()来是实现,其中getBeanFactoryPostProcessors()返回的是Spring容器书刷新之前,开发人员通过手动的方式添加进来的BeanFactoryPostProcessors,如果没有手动添加,就为null

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {

    // 重点
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

    // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
    // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
    // 关于LoadTimeWeaver看这篇文章了解即可,https://www.cnblogs.com/wade-luffy/p/6073702.html
    if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}

在invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())内部,会去判断当前的beanFactory是否是BeanDefinitionRegistry,如果不是BeanDefinitionRegistry的实现类,那么就直接去遍历手动设置的BeanFactoryPostProcessor,调用其postProcessBeanFactory()方法

BeanFactoryPostProcessor分为两类:BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor;后者继承自前者,但又新增了postProcessBeanDefinitionRegistry()方法,可以通过BeanDefinitionRegistry来注册新的BeanDefinition,而BeanFactoryPostProcessor的postProcessBeanFactory()只能去修改BeanDefinition

大多数情况下使用的都是BeanDefinitionRegistryPostProcessor的实现类

1.1 处理手动添加的BeanFactoryPostProcessor

上面说了BeanFactoryPostProcessor分为两类,这两类分别用不同列表regularPostProcessors和registryProcessors存储

beanFactoryPostProcessors集合一般情况下都是空的,除非我们手动调用容器的addBeanFactoryPostProcessor方法添加了,beanFactoryPostProcessors中可能包含了:普通BeanFactoryPostProcessor对象和BeanDefinitionRegistryPostProcessor对象,对于BeanDefinitionRegistryPostProcessor对象,会执行自己的postProcessBeanDefinitionRegistry()方法

将手动添加的BeanFactoryPostProcessor放置到不同的集合中,供后续使用

BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
    if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
        BeanDefinitionRegistryPostProcessor registryProcessor =
            (BeanDefinitionRegistryPostProcessor) postProcessor;
        registryProcessor.postProcessBeanDefinitionRegistry(registry);
        registryProcessors.add(registryProcessor);
    }
    else {
        regularPostProcessors.add(postProcessor);
    }
}
1.2 扫描BeanDefinitionRegistryPostProcessor,执行postProcessBeanDefinitionRegistry()

获取所有所有BeanDefinitionRegistryPostProcessor类型的BeanDefinition的beanName,然后首先判断是否实现了PriorityOrdered接口,实现了该接口的BeanFactoryPostProcessor优先处理,如果实现了该接口,则添加到currentRegistryProcessors缓存中,这个缓存中存的是具体的bean实例,然后把该bean实例的beanName缓存到processedBeans,表示该BeanDefinitionRegistryPostProcessor实例已经执行过了

然后对所有实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor根据order进行排序,order值越小,优先级越高

然后将排序后的BeanDefinitionRegistryPostProcessor实例存入到registryProcessors缓存中,最后遍历这些实例,调用其postProcessBeanDefinitionRegistry()

String[] postProcessorNames =
      beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
   if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
      currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
      processedBeans.add(ppName);
   }
}
// 升序排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());

执行完实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor实例方法后,再去获取一遍BeanDefinitionRegistryPostProcessor的beanName,因为在上面个执行postProcessBeanDefinitionRegistry()的过程中,可能又会增加新的BeanFactoryPostProcessor,如果在这个过程中得到了实现PriorityOrdered接口的实例,这一步也可以执行

得到所有的BeanFactoryPostProcessor后,过滤出实现了Ordered接口实例,然后同上面一样,根据Order值去排序,以及执行实例的postProcessBeanDefinitionRegistry()

postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
   // processedBeans表示该beanFactoryPostProcessor的postProcessBeanDefinitionRegistry()方法已经执行过了,不再重复执行
   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, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();

最后,执行所有没有实现PriorityOrdered或Ordered接口的普通BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry(),在这个过程中可能会向BeanFactory中注册另外的BeanDefinitionRegistryPostProcessor,所以需要while,直到确定所有的BeanDefinitionRegistryPostProcessor都执行完了

在这个过程中注册的BeanDefinitionRegistryPostProcessor,所实现的PriorityOrdered或Ordered接口可能会不按顺序执行

比如 A注册了B和C,B又注册了D和E,那么B和C会按顺序执行,D和E也会按顺序执行,但是B、C、D、E整体不能保证是顺序执行

通过reiterate表示是否有新的BeanDefinitionRegistryPostProcessor加入进来

boolean reiterate = true;
while (reiterate) {
   reiterate = false;
   postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
   for (String ppName : 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, beanFactory.getApplicationStartup());
   currentRegistryProcessors.clear();
}
1.3 执行BeanDefinitionRegistryPostProcessor的postProcessBeanFactory()方法

上一步中,扫描得到了所有的BeanDefinitionRegistryPostProcessor的实例,并且已经执行完了其postProcessBeanDefinitionRegistry(),最后再遍历所有的BeanDefinitionRegistryPostProcessor实例,执行postProcessBeanFactory()方法,以及遍历手动添加的普通BeanFactoryPostProcessor,调用其postProcessBeanFactory()

// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
// 执行完BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法后,
// 再执行BeanDefinitionRegistryPostProcessor的postProcessBeanFactory()方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);

// 执行手动添加的普通BeanFactoryPostProcessor的postProcessBeanFactory()方法
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
1.4 扫描BeanFactoryPostProcessor执行postProcessBeanFactory方法

前面处理的都是实现了BeanDefinitionRegistryPostProcessor的实例,处理完之后,该处理普通的BeanFactoryPostProcessor接口的实例,普通的实例又分为实现了PriorityOrdered或Ordered接口和两者都没实现的,对于这三种,分别处理,优先级与上面BeanDefinitionRegistryPostProcessor实例的一致

// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames =
      beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();

将普通的BeanFactoryPostProcessor进行分来

因为BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProcessor接口,所有前面已经执行过的实例,也会被查出来,对已经执行的实例进行过滤

// 先进行分类
for (String ppName : postProcessorNames) {
   if (processedBeans.contains(ppName)) {
      // skip - already processed in first phase above
   }
   else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
      priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
   }
   else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
      orderedPostProcessorNames.add(ppName);
   }
   else {
      nonOrderedPostProcessorNames.add(ppName);
   }
}

依次获取这三类BeanFactoryPostProcessor的实例,然后调用

// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
   orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
   nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

二、 BeanPostProcessor实例化

在执行BeanDefinitionRegistryPostProcessors和BeanFactoryPostProcessor的方法时,会去扫描配置类,生成对应的BeanDefinition,配置类的扫描细节会在后续的文章中讲到,我们只需要知道在postProcessBeanDefinitionRegistry()方法中会去扫描配置类,这里面就包含很多我们可以自定义的和Spring自带的BeanPostProcessor,扫描过程中会将这些BeanPostProcessor都生成BeanDefinition

registerBeanPostProcessors(beanFactory);

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

同样会根据类型获取到所有BeanPostProcessor的beanName,然后同样按照PriorityOrdered、Ordered进行分类,然后加入到beanFactory的beanPostProcessors中

在添加其他BeanPostProcessor之前,会首先添加一个的BeanPostProcessorChecker实例

String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
// beanProcessorTargetCount表示BeanFactory中所有的BeanPostProcessor数量,+1表示BeanPostProcessorChecker
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

对BeanPostProcessor进行分类

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

分完类之后,对这些实现了PriorityOrdered和Ordered接口的BeanPostProcessor实例根据Order值进行排序,值越小,优先级越高

registerBeanPostProcessors()用于将BeanPostProcessor实例放入到beanFactory的beanPostProcessors缓存中,Bean实例化过程中用到的BeanPostProcessor都在这个里面

// First, register the BeanPostProcessors that implement PriorityOrdered.
// 升序排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
   BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
   orderedPostProcessors.add(pp);
   if (pp instanceof MergedBeanDefinitionPostProcessor) {
      internalPostProcessors.add(pp);
   }
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);

// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
   BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
   nonOrderedPostProcessors.add(pp);
   if (pp instanceof MergedBeanDefinitionPostProcessor) {
      internalPostProcessors.add(pp);
   }
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

严格来说,BeanPostProcessor是分为四类,其中实现了MergedBeanDefinitionPostProcessor的实例单独缓存了,放在所有BeanPostProcessor的最后面

在最后,会添加一个ApplicationListenerDetector实例,用于在Bean初始化后,判断bean是否实现了ApplicationListener接口,如果是则将该bean实例添加到ApplicationContext的applicationListeners缓存中

/ Finally, re-register all internal BeanPostProcessors.
// MergedBeanDefinitionPostProcessor排在最后
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);

// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
// ApplicationListenerDetector放在所有BeanPostProcessor之后,注意ApplicationListenerDetector的equals()方法实现
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/112154.html

(0)
Java光头强的头像Java光头强

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!