• 从零开始学spring源码之ioc预热:bean的拓展和beanProcessor注册


        上篇聊完了bean的解析,说起来做的事情很简单,把xml文件里面配置的标签全部解析到spring容器里面,但是spring做的时候,花了那么大代价去做,后面看看到底值不值得呢。

        接下来看看prepareBeanFactory(beanFactory)方法,点进去看一下:

    public static void invokeBeanFactoryPostProcessors(
    ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

    // Invoke BeanDefinitionRegistryPostProcessors first, if any.
    Set<String> processedBeans = new HashSet<>();

    if (beanFactory instanceof BeanDefinitionRegistry) {
    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);
    }
    }

    // Do not initialize FactoryBeans here: We need to leave all regular beans
    // uninitialized to let the bean factory post-processors apply to them!
    // Separate between BeanDefinitionRegistryPostProcessors that implement
    // PriorityOrdered, Ordered, and the rest.
    List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

    //1.调用实现了PriorityOrdered 的BeanDefinitionRegistryPostProcessors
    // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
    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);
    currentRegistryProcessors.clear();

    //2.调用实现了Ordered 的BeanDefinitionRegistryPostProcessors
    // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
    postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    for (String ppName : 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();

    //3.调用其他剩余的BeanDefinitionRegistryPostProcessors
    // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
    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);
    currentRegistryProcessors.clear();
    }

    //4.调用所有实现了BeanFactoryPostProcessor类并重写了postProcessBeanFactory方法的回调
    // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
    invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    }

    else {
    // Invoke factory processors registered with the context instance.
    invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }

    // 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<>();
    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);
    }
    }

    // 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<>();
    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<>();
    for (String postProcessorName : nonOrderedPostProcessorNames) {
    nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

    // Clear cached merged bean definitions since the post-processors might have
    // modified the original metadata, e.g. replacing placeholders in values...
    beanFactory.clearMetadataCache();
    }

    我的天哪,又是这么长的代码,仔细一看,好多重复的代码,这块重复的代码封装一下是不是很完美(小声bb),仔细分析之后(主要还是靠之前的大牛们写的博客),其实做的主要就是4件事:

    1.调用实现了PriorityOrdered 的BeanDefinitionRegistryPostProcessors
    2.调用实现了Ordered 的BeanDefinitionRegistryPostProcessors
    3.调用其他剩余的BeanDefinitionRegistryPostProcessors
    4.调用所有实现了BeanFactoryPostProcessor类并重写了postProcessBeanFactory方法的回调
    我们首先看前三步调用的BeanDefinitionRegistryPostProcessors是在干啥,核心代码其实就是上面标红的代码,点进去:
    private static void invokeBeanDefinitionRegistryPostProcessors(
                Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
    
            for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
                postProcessor.postProcessBeanDefinitionRegistry(registry);
            }
        }

    这块只做了一个遍历,然后调用postProcessBeanDefinitionRegistry方法,这个方法又是干啥的呢,点进去是一个抽象类,我们先不管这个是干嘛的,看一下我写的一个类:

    @Component
    public class BeanDefinitionTest implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
    genericBeanDefinition.setBeanClass(BeanClass.class);

    // genericBeanDefinition.getConstructorArgumentValues().addGenericArgumentValue(null);

    MutablePropertyValues propertyValues = genericBeanDefinition.getPropertyValues();
    propertyValues.addPropertyValue("username","peter");

    registry.registerBeanDefinition("beanClass",genericBeanDefinition);

    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    System.out.println(beanFactory.getBean("beanClass"));
    }
    }

           可以看到BeanDefinitionTest实现了 BeanDefinitionRegistryPostProcessor ,我重写了BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法和BeanFactoryPostProcessor的postProcessBeanFactory方法,你会发现其实上面前3步调用的方法和第4步调用的方法,就是我这边重写的两个方法,感兴趣的同学可以自己写一下,启动容器的时候debug看看。那么这两个方法是做什么的呢,不知道还记不记得前面注册beanDefinition的时候,其实就是用BeanDefinitionRegistry 注册的。而beanFactory是存储所有beanDefinition对象的容器,拿到它就相当于拿到了所有的beanDefinition对象。好像还是很厉害的,实现了这一个方法,既可以添加自定义的bean,又可以自己修改已经有的bean对象,spring大法牛逼。

         接下来再看一下beanPostProcessor的注册:

    public static void registerBeanPostProcessors(
    ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

    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.
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

    // Separate between BeanPostProcessors that implement PriorityOrdered,
    // Ordered, and the rest.
    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);
    }
    }

    //1.注册实现了PriorityOrdered的beanPostProcessor
    // First, register the BeanPostProcessors that implement PriorityOrdered.
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    //2.注册实现了Ordered的beanPostProcessor
    // Next, register the BeanPostProcessors that implement Ordered.
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
    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);

    //3.注册没用实现排序的beanPostProcessor
    // Now, register all regular BeanPostProcessors.
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
    for (String ppName : nonOrderedPostProcessorNames) {
    BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
    nonOrderedPostProcessors.add(pp);
    if (pp instanceof MergedBeanDefinitionPostProcessor) {
    internalPostProcessors.add(pp);
    }
    }
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

    //4.重新注册所有的的beanPostProcessor
    // Finally, re-register all internal BeanPostProcessors.
    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).
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }

    主要还是分为4步:

     1.注册实现了PriorityOrdered的beanPostProcessor

     2.注册实现了Ordered的beanPostProcessor

     3.注册没有实现排序接口的beanPostProcessor

     4.重新注册所有的的beanPostProcessor

    而注册的具体逻辑又分为几步:

    1.getBean获取BeanProcessor实例

    2.加入容器

    3.排序后注册

    在这里,很多我们后面aop或者其他地方需要用的到处理器类就都已经实例化完成了,刚开始接触的时候都说这叫bean的后置处理器,因此,一直纠结于在bean实例化完成后才会去执行,可实际研究源码的时候,发现并不是我想的这样,因此困扰了很久。

    其实就是一个处理器类吧,在bean初始化前后都会去调用,让我们自己去做一些定制化的修改,而且可以实现排序接口,实现执行的先后顺序。

    总结:

            刚开始接触spring源码的时候,这块的源码总是无法理解,因为脑子里面的固有思维是spring做的肯定是去加载,注册,实例化bean的,对于框架的拓展性,高可用没有什么概念,像这个方法里面基本上除了为了提前能调用到我添加的类,会去调用getBean方法提前实例化,其他的基本都是为了让使用者可以更自由的去拓展。我想,以后在我自己去写代码的时候,也会去多考虑这些吧。

  • 相关阅读:
    CentOS上手动配置nginx.services
    Mac安装软件时,提示文件已损坏,需要移动到废纸篓的解决方法
    Jumpserver安装部署
    Linux服务器测试带宽
    Zabbix_server执行window脚本出现中文乱码如何解决
    四行shell脚本实现Zabbix_server 的高可用
    Kubernetes Pod故障归类与排查方法
    Nginx配置location与rewrite规则教程
    ipa文件信息检查工具
    申请免费SSL证书
  • 原文地址:https://www.cnblogs.com/gmt-hao/p/13039820.html
Copyright © 2020-2023  润新知