深入理解Spring IOC(三) 、refresh方法中实例化前的准备工作

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 深入理解Spring IOC(三) 、refresh方法中实例化前的准备工作

1.BeanDefinition的注册


在我们之前的文章中,我们已经把xml中的信息解析成了BeanDefiniton,然后我们需要注册他,其实所谓的注册也就是把解析出来的BeanDefiniton放到一个容器中去,以便在后边实例化的时候进行统一实例化。我们来看看下面的代码:


代码块1
        @Override
  protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    // 1.我们前文所说过的XmlBeanDefinitionReader
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
    // 2.现在是在AbstractXmlApplicationContext,其父类既继承了DefaultResourceLoader的,也
    // 实现了ResourcePatternResolver
    beanDefinitionReader.setEnvironment(this.getEnvironment());
    beanDefinitionReader.setResourceLoader(this);
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
    // 3.设置验证模型
    initBeanDefinitionReader(beanDefinitionReader);
    // 4.加载Resource
    loadBeanDefinitions(beanDefinitionReader);
  }


这断代码相信大家已经很熟悉了吧,我们可以看到这个代码块的1处new了一个XmlBeanDefinitionReader,我们注意到,new的同时传了一个DefaultListableBeanFactory,这个DefaultListableBeanFactory它实现了了BeanDefinitionRegistry接口,换句话说,它也是一个BeanDefinitionRegistry的实例,这个东西起到了什么作用呢?我们来看看下面的中的第2处中代码调用方法的参数:


代码块2
        protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
    if (bdHolder != null) {
      // 1.解析默认标签下的自定义标签
      bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
      try {
        // 2.注册beanDefiniton实例.
        BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
      }
      catch (BeanDefinitionStoreException ex) {
        getReaderContext().error("Failed to register bean definition with name '" +
            bdHolder.getBeanName() + "'", ele, ex);
      }
      // Send registration event.
      getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
    }
  }


这也是之前文章中的代码了,第2处调用的方法的第二个参数这个getReaderContext().getRegistry()方法返回的,就是上面DefaultListableBeanFactory的实例,我们直接点进2处BeanDefinitionReaderUtils的registerBeanDefinition方法来看:


代码块3
        public static void registerBeanDefinition(
      BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
      throws BeanDefinitionStoreException {
    // 1.注册beanDefinition
    String beanName = definitionHolder.getBeanName();
    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
    // 2.注册别名
    String[] aliases = definitionHolder.getAliases();
    if (aliases != null) {
      for (String aliase : aliases) {
        registry.registerAlias(beanName, aliase);
      }
    }
  }


我们着重看1处,之前也说过,这个registry实际上就是个DefaultListableBeanFactory的实例,因此我们顺着这个类来找到DefaultListableBeanFactory里 的registerBeanDefinition方法:


代码块4
        @Override
  public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
      throws BeanDefinitionStoreException {
    Assert.hasText(beanName, "Bean name must not be empty");
    Assert.notNull(beanDefinition, "BeanDefinition must not be null");
    if (beanDefinition instanceof AbstractBeanDefinition) {
      try {
        // 1.校验,主要是校验method-override 和 factory-method(这两个不能共存)
        ((AbstractBeanDefinition) beanDefinition).validate();
      }catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
            "Validation of bean definition failed", ex);
      }
    }
    BeanDefinition oldBeanDefinition;
    // 为什么要synchronized,因为其实ConcurrentHashMap并非绝对的线程安全
    synchronized (this.beanDefinitionMap) {
      oldBeanDefinition = this.beanDefinitionMap.get(beanName);
      if (oldBeanDefinition != null) {
        // 2.allowBeanDefinitionOverriding默认是true
        if (!this.allowBeanDefinitionOverriding) {
          throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
              "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
              "': There is already [" + oldBeanDefinition + "] bound.");
        // 3. bean的role 表示beanDefiniton的种类,是个int类型的变量,你可以理解成这个数字越大其代表的beanDefinition就越底层
        // 例如 1是用户定义的,2和3就都是配置相关的,只是配置级别不一样
        } else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
          if (this.logger.isWarnEnabled()) {
            this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +
                " with a framework-generated bean definition ': replacing [" +
                oldBeanDefinition + "] with [" + beanDefinition + "]");
          }
        } else {
          if (this.logger.isInfoEnabled()) {
            this.logger.info("Overriding bean definition for bean '" + beanName +
                "': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
          }
        }
      } else {
          // 把beanName放到专门用于存bean名称的集合用于后续创建对象用
        this.beanDefinitionNames.add(beanName);
        this.frozenBeanDefinitionNames = null;
      }
      // 4. 真真正正的注册,其实就是将这个beanDefinition放到一个map中
      this.beanDefinitionMap.put(beanName, beanDefinition);
    }
    if (oldBeanDefinition != null || containsSingleton(beanName)) {
      resetBeanDefinition(beanName);
    }
  }


我们可以看到,在4这个地方,将所有的解析好的BeanDefinition放到了一个Map容器中,到这里,完成了BeanDefinition的注册。


2.AbstractApplicationContext的refresh


可总算是到这里了,因为很多人看spring源码就是从这里开始的,也有很多人可能也就知道这个方法。总之今天会让你知道更多,我们直接到refresh方法这里:


代码块5
        @Override
  public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
      // 1.加载前的准备工作
      prepareRefresh();
      // 2.获取一个全新的beanFactory实例
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
      // 3.初始化beanFactory,给它设置各种
      prepareBeanFactory(beanFactory);
      try {
        // (空方法,让子类重写的)允许对beanFactory中的东西做一些前置的修改,可以是增加个BeanFactoryPostProcessors
        // 这种的,也可以给增加个BeanDefinition,也可以增加一些让beanFactory在自动装配时候忽略掉的接口,也可以增加一些特定场景使用的bean,
        // 比如有的后代就增加了新的scope bean 等等。但是重点是,我刚才说的这些都是基于一种具体场景的,因此这个抽象类里,
        // 这个方法是空的(不弄成抽象的原因是不强迫子类去实现)
        postProcessBeanFactory(beanFactory);
        // 4.触发调用所有的BeanFactoryPostProcessors(后边会讲这是个啥)
        invokeBeanFactoryPostProcessors(beanFactory);
        // 5.注册所有的BeanPostProcessor(后边会说)
        registerBeanPostProcessors(beanFactory);
        // 6.初始化支持国际化的东东
        initMessageSource();
        // 7. 初始化事件广播器
        initApplicationEventMulticaster();
        // 8. 初始化其他特殊的bean
        onRefresh();
        // 9. 注册监听器
        registerListeners();
        // 10. 实例化bean( 重点 )
        finishBeanFactoryInitialization(beanFactory);
        finishRefresh();
      } catch (BeansException ex) {
        logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex);
        // Destroy already created singletons to avoid dangling resources.
        destroyBeans();
        // Reset 'active' flag.
        cancelRefresh(ex);
        // Propagate exception to caller.
        throw ex;
      }
    }
  }


尽管上面每一步都有注释,但是你肯定还是很懵逼,也不知道里面的方法到底都干了什么,为了容易一点让你理解,在这篇文章里,每一个大的部分都会被拆成很多小的部分讲,接下来我们针对上面代码块的每一个注释,展开说,每个细节都不放过。

在说之前有个需要大家注意的,我是基于之前那篇开始的代码debug,也就是说我们此时还是在用ClassPathXmlApplicationContext这个ApplicationContext的实现类,很多讲源码的文章都是直接说refresh方法,说真的,不基于使用场景去讲这个真的感觉像是在耍流氓。好了,吐槽的话说完了,我们开始

5.1

代码块5中1处调用的prepareRefresh主要是做的加载前的准备工作,我们直接来看prepareRefresh方法都做了什么


代码块6
        protected void prepareRefresh() {
    // 1. 记录下容器开始刷新的时间
    this.startupDate = System.currentTimeMillis();
    // 2. 把容器标为激活状态
    synchronized (this.activeMonitor) {
      this.active = true;
    }
    if (logger.isInfoEnabled()) {
      logger.info("Refreshing " + this);
    }
    // 3. ClassPathXmlApplicationContext的时候调的是个空方法,跳过~
    initPropertySources();
    // 4. 调用StandardEnvironment中的validateRequiredProperties方法
    getEnvironment().validateRequiredProperties();
  }


上面的1、2、3处很容易理解,我们直接看4处的validateRequiredProperties方法,这块的这个代码其实是在AbstractEnvironment中:


代码块7
        @Override
  public void validateRequiredProperties() throws MissingRequiredPropertiesException {
    this.propertyResolver.validateRequiredProperties();
  }


这里的这个propertyResolver是个PropertySourcesPropertyResolver的实例,这个玩意是用来解析存放一些环境变量以及配置用的(比如springboot的properties和yml的属性最后都会存放到这里面的propertySources中),我们直接来看PropertySourcesPropertyResolver的validateRequiredProperties方法,其实它是直接继承的AbstractPropertyResolver的这个方法:


代码块8
        @Override
  public void validateRequiredProperties() {
    // 先new个异常
    MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();
    // 如果需要的属性为空那么就把上一句new出来的异常抛出去
    for (String key : this.requiredProperties) {
      if (this.getProperty(key) == null) {
        ex.addMissingRequiredProperty(key);
      }
    }
    if (!ex.getMissingRequiredProperties().isEmpty()) {
      throw ex;
    }
  }


但是哈,debug的时候这个this.requiredProperties其实是空的,这是因为在创建StandardEnvironment的时候并没有去调用setRequiredProperties去添加必须属性,所以这个方法其实在我们讲的这个背景下p都没有干,但是我们还是需要注意PropertySourcesPropertyResolver(你最少要知道它是什么),因为这玩意在SpringBoot中是很重要的。


5.2

代码块5中2处这里主要的目的是获取一个全新的DefaultListableBeanFactory,并且,把xml中对应的信息加载成BeanDefinition放到这里面去。加载的过程我们之前文章就是专门讲的这个,这里不再赘述。


5.3

这里主要还是一些初始化工作


代码块9
    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // Tell the internal bean factory to use the context's class loader etc.
        //设置类加载器:存在则直接设置/不存在则新建一个默认类加载器
    beanFactory.setBeanClassLoader(getClassLoader());
    //设置EL表达式解析器(Bean初始化完成后填充属性时会用到)
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
    //设置属性注册解析器PropertyEditor
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    // Configure the bean factory with context callbacks.
      // 将当前的ApplicationContext对象交给ApplicationContextAwareProcessor类来处理,
    // 从而在Aware接口实现类中的注入applicationContext
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    //设置忽略自动装配的接口
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    // 注册可以解析的自动装配
    // BeanFactory interface not registered as resolvable type in a plain factory.
    // MessageSource registered (and found for autowiring) as a bean.
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);
    //如果当前BeanFactory包含loadTimeWeaver Bean,说明存在类加载期织入AspectJ,
    //则把当前BeanFactory交给类加载期BeanPostProcessor实现类LoadTimeWeaverAwareProcessor来处理,
    //从而实现类加载期织入AspectJ的目的。
    // Detect a LoadTimeWeaver and prepare for weaving, if found.
    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      // Set a temporary ClassLoader for type matching.
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
    //注册当前容器环境environment组件Bean
    // Register default environment beans.
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    //注册系统配置systemProperties组件Bean
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    //注册系统环境systemEnvironment组件Bean
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
  }


虽然能给的注释我都给了,但是我估计你看到这个还是一脸懵逼,根本不知道这些东西是干什么用的,实在不明白,可以先混个脸熟,等后边看完了再返回到这里看。


5.4

这里是触发所有的BeanFactoryPostProcessor,关于BeanFactoryPostProcessor,接下来会有一篇扩展篇,专门说这个。我们在这里,可以先看这里的代码,因为这块其实很容易理解。


代码块10
        protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
  }


我们可以看到,又是个delegate,那我们就直接去delegate里面去看:


代码块11
        public static void invokeBeanFactoryPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    // 已经实例化过的processor的集合
    Set<String> processedBeans = new HashSet<String>();
    // 首先调用BeanDefinitionRegistryPostProcessors
    // 因为参数中的beanFactory是DefaultListableBeanFactory的实例,而DefaultListableBeanFactory实现了
    // BeanDefinitionRegistry,因此,if的条件是true
    if (beanFactory instanceof BeanDefinitionRegistry) {
      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      // regularPostProcessors 是放普通的BeanFactoryPostProcessor的
      List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
      // 而这个registryPostProcessors是放BeanDefinitionRegistryPostProcessor的
      // 注意:BeanDefinitionRegistryPostProcessor接口继承了BeanFactoryPostProcessor
      List<BeanDefinitionRegistryPostProcessor> registryPostProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>();
      for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
        // 如果BeanFactoryPostProcessor是BeanDefinitionRegistryPostProcessor,
        if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
          BeanDefinitionRegistryPostProcessor registryPostProcessor =
              (BeanDefinitionRegistryPostProcessor) postProcessor;
          // 执行BeanDefinitionRegistryPostProcessor,并加入registryPostProcessors集合
          registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
          registryPostProcessors.add(registryPostProcessor);
        // 否则只加入regularPostProcessors集合
        } else {
          regularPostProcessors.add(postProcessor);
        }
      }
      String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      // 首先调用实现了 PriorityOrdered 的 BeanDefinitionRegistryPostProcessors
      List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
      for (String ppName : postProcessorNames) {
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
          // 注意,这里实例化了BeanDefinitionRegistryPostProcessor
          priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
          processedBeans.add(ppName);
        }
      }
      // 这个排序呢,其实是为了调整好那种既实现了PriorityOrdered,和Ordered的BeanDefinitionRegistryPostProcessor
      // 因为实现了PriorityOrdered也可以同时实现Ordered(虽然PriorityOrdered继承了Ordered,)在同时实现这两个接口的情况
      // 下,如果不排序,但是你的BeanDefinitionRegistryPostProcessor又需要这种执行顺序时候,在下面invoke的时候就会有问题
      // 接下来的排序也是这个道理
      OrderComparator.sort(priorityOrderedPostProcessors);
      // 把实现了 PriorityOrdered 的放到之前的 registryPostProcessors 中
      registryPostProcessors.addAll(priorityOrderedPostProcessors);
      // 执行实现了 PriorityOrdered 的 BeanDefinitionRegistryPostProcessor
      invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);
      // 然后调用实现了 Ordered 的 BeanDefinitionRegistryPostProcessors
      // 为什么要重新拿这个数组呢?因为实现了 PriorityOrdered 的 BeanDefinitionRegistryPostProcessor 可以给你注册了实现
      // Ordered 和什么排序接口都没有的 BeanDefinitionRegistryPostProcessor
      postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
      for (String ppName : postProcessorNames) {
        // 执行过的跳过不执行
        if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
          orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
          processedBeans.add(ppName);
        }
      }
      OrderComparator.sort(orderedPostProcessors);
      registryPostProcessors.addAll(orderedPostProcessors);
      invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);
      // 最后调用实现了其他的BeanDefinitionRegistryPostProcessors
      boolean reiterate = true;
      while (reiterate) {
        reiterate = false;
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        // 外层之所以是个while循环,是因为BeanDefinitionRegistryPostProcessor可以再给你
        // 注册个BeanDefinitionRegistryPostProcessor进来,所以要循环执行,只要你的for循环可以进来
        // reiterate这个是否循环的flag就是true
        for (String ppName : postProcessorNames) {
          if (!processedBeans.contains(ppName)) {
            BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
            registryPostProcessors.add(pp);
            processedBeans.add(ppName);
            pp.postProcessBeanDefinitionRegistry(registry);
            reiterate = true;
          }
        }
      }
      // 都是调用BeanFactoryPostProcessor的方法postProcessBeanFactory
      invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
      invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    }else {
      invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }
    // 这里有个很大的注意点哦:上面的逻辑都是在调用入参的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor
    // 而接下来的是调用beanFactory容器中的BeanFactoryPostProcessor,逻辑和上面类似,也是按实现PriorityOrdered,Ordered
    // 和普通的来调用。至于为什么要先调用BeanDefinitionRegistryPostProcessors然后调用BeanFactoryPostProcessor呢?这是因为
    // BeanDefinitionRegistryPostProcessors也可以注册新的BeanFactoryPostProcessor进来
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    // 三个优先级的BeanFactoryPostProcessor的集合
    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)) {
      // PriorityOrdered加进高优先级的集合,并优先初始化
      } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
        priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
      // Ordered的加进一般优先级集合
      } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
        orderedPostProcessorNames.add(ppName);
      // 加入普通集合
      } else {
        nonOrderedPostProcessorNames.add(ppName);
      }
    }
    // 排序并调用高优先级的BeanFactoryPostProcessor
    OrderComparator.sort(priorityOrderedPostProcessors);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    // 初始化一般优先级BeanFactoryPostProcessor并排序调用
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    for (String postProcessorName : orderedPostProcessorNames) {
      orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    OrderComparator.sort(orderedPostProcessors);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    // 初始化普通的BeanFactoryPostProcessor并排序调用
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    for (String postProcessorName : nonOrderedPostProcessorNames) {
      nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
  }


代码比较长,但是思路还是很清晰的,总体也就是先按顺序调用BeanDefinitionRegistryPostProcessor,然后按同样的顺序调用BeanFactoryPostProcessor。


5.5

这里是注册所有的BeanPostProcessor的,注意哈,不会调用的,因为这个BeanPostProcessor必须等到Bean初始化之后才可以被调用。我会在和BeanFactoryPostProcessor同一篇文章中去说这个BeanPostProcessor。我们同样的可以直接来看注册BeanPostProcessor的源码(因为简单😊),还是在和上面代码块相同的一个类中,只不过是另外一个方法:


代码块12
        public static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
    // 拿到所有的BeanPostProcessor名称
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
    // 优先注册一个BeanPostProcessorChecker的实例,这玩意是用作在BeanPostProcessor初始化的这个过程
    // 做检查用的,检查内容见扩展篇
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
    // 还是熟悉的套路,将三种优先级别的BeanPostProcessor分开
    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) {
      // 先实例化实现了PriorityOrdered的,并加入集合
      if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        priorityOrderedPostProcessors.add(pp);
        // 如果是MergedBeanDefinitionPostProcessor,则加入internalPostProcessors
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
          internalPostProcessors.add(pp);
        }
      } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
        orderedPostProcessorNames.add(ppName);
      } else {
        nonOrderedPostProcessorNames.add(ppName);
      }
    }
    // 排序并注册
    OrderComparator.sort(priorityOrderedPostProcessors);
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
    // 接着注册实现了Ordered的
    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);
    // 重新注册所有的实现了MergedBeanDefinitionPostProcessor的(为了移动到处理链路的最后一个)
    // 不明白什么是处理链路的先往下看,到后边自然会明白
    OrderComparator.sort(internalPostProcessors);
    registerBeanPostProcessors(beanFactory, internalPostProcessors);
    // 重新注册ApplicationListenerDetector(也是为了移动到处理链路的最后一个)
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
  }


实际上和之前注册BeanFactoryPostProcessor的方式类似,这里不做过多的解释,看注释即可。


代码块5的6、7、8、9这四处代码不属于核心流程,我们暂时不关注这些。至此,实例化bean的前期准备工作已经做完。我们总结一下,使用xml的这种情况下,在refresh方法中bean实例化之前,主要干了这么几件事,首先需要把所有的BeanDefinition加载进BeanFactory容器这个是在refresh的第二步做的,接下来是需要在prepareBeanFactory中率先初始化一些基本的bean,然后是调用所有的BeanFactoryPostProcessor去对BeanDefinition做后置处理,接着去注册所有的BeanPostProcessor,再下来是国际化、事件广播器以及监听器的初始化。在这其中,最重要的,是加载BeanDefinition这步以及调用BeanFactoryPostProcessor的这步,因为这两步中,我们都是可以插手去做扩展的。

目录
相关文章
|
21天前
|
Java Spring 容器
Spring IOC、AOP与事务管理底层原理及源码解析
【10月更文挑战第1天】Spring框架以其强大的控制反转(IOC)和面向切面编程(AOP)功能,成为Java企业级开发中的首选框架。本文将深入探讨Spring IOC和AOP的底层原理,并通过源码解析来揭示其实现机制。同时,我们还将探讨Spring事务管理的核心原理,并给出相应的源码示例。
77 9
|
18天前
|
存储 开发框架 Java
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
文章详细介绍了Spring、IOC、DI的概念和关系,解释了控制反转(IOC)和依赖注入(DI)的原理,并提供了IOC的代码示例,阐述了Spring框架作为IOC容器的应用。
17 0
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
|
5天前
|
XML Java 数据格式
Spring IOC容器的深度解析及实战应用
【10月更文挑战第14天】在软件工程中,随着系统规模的扩大,对象间的依赖关系变得越来越复杂,这导致了系统的高耦合度,增加了开发和维护的难度。为解决这一问题,Michael Mattson在1996年提出了IOC(Inversion of Control,控制反转)理论,旨在降低对象间的耦合度,提高系统的灵活性和可维护性。Spring框架正是基于这一理论,通过IOC容器实现了对象间的依赖注入和生命周期管理。
17 0
|
13天前
|
XML Java 数据格式
Spring的IOC和AOP
Spring的IOC和AOP
33 0
|
1月前
|
SQL 监控 druid
springboot-druid数据源的配置方式及配置后台监控-自定义和导入stater(推荐-简单方便使用)两种方式配置druid数据源
这篇文章介绍了如何在Spring Boot项目中配置和监控Druid数据源,包括自定义配置和使用Spring Boot Starter两种方法。
|
10天前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
56 2
|
2月前
|
缓存 Java Maven
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
|
10天前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
22 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
3月前
|
Java 测试技术 数据库
Spring Boot中的项目属性配置
本节课主要讲解了 Spring Boot 中如何在业务代码中读取相关配置,包括单一配置和多个配置项,在微服务中,这种情况非常常见,往往会有很多其他微服务需要调用,所以封装一个配置类来接收这些配置是个很好的处理方式。除此之外,例如数据库相关的连接参数等等,也可以放到一个配置类中,其他遇到类似的场景,都可以这么处理。最后介绍了开发环境和生产环境配置的快速切换方式,省去了项目部署时,诸多配置信息的修改。