【Spring源码】一个我们日常接触的ApplicationContext

简述

回顾一下上一篇,使用的是一个简单的 BeanFactory 实现 XmlBeanFactory。这个容器已经是一个过时的容器了,因为他并不能实现除了注册 BeanDefinition 之外的事情(比如 i18n 访问资源(骚一点的话可以加载网络 Spring 配置文件) 应用事件)。所以,就有了 spring-context 的出现。

我们现在知道了,Spring 把载入、解析、注册解耦成不同的模块,所以我们现在可以大概的知道:

  1. 载入:我们可以使用不同的方式载入配置文件,然后配置解析方式,生成 BeanDefinition 注册到底层的 Bean 容器中;
  2. 解析:不同的配置文件解析方式有所不同,但是有个共同的目的就是解析成 BeanDefinition 注册到容器中去;
  3. 注册:这块 Spring 已经提供了 DefaultListableBeanFactory 这个成熟的实现,所以即使我们想通过其他配置文件来配置我们的 Spring 项目的话,不用慌,只要用它就好了(奥森!)

那么仔细想想,我们是不是可以实现由 JSON 格式配置文件来配置的 BeanFactory

一.一个可运行的DEMO

因为 Spring 现在支持 Java注解 来生成对象,所以我想在看 ApplicationContext 源码的时候,顺便把怎么从配置里面取出 Bean 的过程给看了,所以配置文件只配置了一个 Java配置类。

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
">

    <bean class="cn.liweidan.confbean.MyBeanConfiguration"/>
    <context:annotation-config/>
</beans>

MyBeanConfiguration.java

这个写法在 SpringBoot 横行霸道的时候应该不会陌生。

package cn.liweidan.confbean;

import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;

@Configurable
public class MyBeanConfiguration {

  @Bean
  public MyBean myBean() {
    MyBean myBean = new MyBean();
    myBean.setName("Weidan");
    return myBean;
  }

}

MyBean.java

package cn.liweidan.confbean;

public class MyBean {

  private String name;

  public MyBean(String name) {
    this.name = name;
  }

  public MyBean() {
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }
}

启动器

package cn.liweidan.confbean;

import org.junit.Assert;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ConfigBeanTest {

  @Test
  public void testConfigBean() {
    BeanFactory bf = new ClassPathXmlApplicationContext("applicationContext.xml");
    MyBean bean = bf.getBean(MyBean.class);
    Assert.assertNotNull(bean);
  }

}

跑一下测试用例,恩!是绿色的感觉!(绿色?)

二.源码解析

其实我一直没有经验怎么写源码的解析,看得人才能容易看的明白,所以我就按照 debug 走的顺序来走了,在哪个类的哪个方法,都会放在三级标题上。

《【Spring源码】一个我们日常接触的ApplicationContext》

好了,我们已经可以看到,application 是一个 BeanFactory 但是他又没有去继承我们之前看到的 BeanFactory 的实现类。为啥,他并不是一个单纯的 BeanFactory 实现,而是聚合了 BeanFactory 实现类,来实现 BeanFactory 的所有功能,所以,它拥有 BeanFactory 接口的所有功能。(还记得那句话吗?接口表示实现类会什么(class has xxx),继承表示实现类是什么(class is xxx))

2.1 ClassPathXmlApplicationContext构造器

好,首先从这段代码开始:

BeanFactory bf = new ClassPathXmlApplicationContext("applicationContext.xml");

ClassPathXmlApplicationContext 其实是一个简单到不能再简单的类了,他的主要功能就是记录用户传递的 applicationContext.xml 的路径,是一个字符串数组:

public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {

    @Nullable
    private Resource[] configResources;

  /** 这是我们进入的时候调用的构造方法 */
    public ClassPathXmlApplicationContext(String... configLocations) throws BeansException {
    // 调用了下面的构造方法
        this(configLocations, true, null);
    }

  public ClassPathXmlApplicationContext(
            String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
            throws BeansException {
    // 这里是一个 Null,我就不进去看了,反正就是之前熟悉的
    // 设置 parentBeanFactory 
        super(parent);
        setConfigLocations(configLocations);
        if (refresh) {
            refresh();
        }
    }

}

OK,接下来我们进入这句话:setConfigLocations(configLocations);

2.2 AbstractRefreshableConfigApplicationContext#setConfigLocations

这句话的实现是在父级 AbstractRefreshableConfigApplicationContext 实现的,先简单了解下这句话是做什么用的,这句话是设置我 AbstractRefreshableConfigApplicationContext 的配置路径的属性,顺便通过环境的配置,把类似于 application-${someProp} 的配置,给还原成我们配置再环境的内容。

先看下代码:

public abstract class AbstractRefreshableConfigApplicationContext extends AbstractRefreshableApplicationContext
        implements BeanNameAware, InitializingBean {

    public void setConfigLocations(@Nullable String... locations) {
        if (locations != null) {
            Assert.noNullElements(locations, "Config locations must not be null");
            this.configLocations = new String[locations.length];
            for (int i = 0; i < locations.length; i++) {
        // 重点要跟着这一句走
                this.configLocations[i] = resolvePath(locations[i]).trim();
            }
        }
        else {
            this.configLocations = null;
        }
    }

    protected String resolvePath(String path) {
        return getEnvironment().resolveRequiredPlaceholders(path);
    }

  /*
      getEnvironment()这一句还是在父类 AbstractApplicationContext 实现的:
    protected ConfigurableEnvironment createEnvironment() {
        return new StandardEnvironment();
    }
  */

}

简单的创建了一个 StandardEnvironment 对象,我想这是因为我在类似于 main 方法运行的缘故,如果是 web 环境有另外一种实现 StandardServletEnvironment

StandardServletEnvironment#resolveRequiredPlaceholders 代码则是把这件事情交给 core 里面的工具类 PropertyPlaceholderHelper#parseStringValue 来实现,由于这件事情不是我要看的重点,所以我先直接跳过去好了。

然后直接下一步,if (refresh) {...} 因为构造器直接写死传递了一个 true,所以现在需要直接进入 refresh() 方法来做。

2.3 AbstractApplicationContext#refresh

    @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                registerBeanPostProcessors(beanFactory);

                // Initialize message source for this context.
                initMessageSource();

                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                onRefresh();

                // Check for listener beans and register them.
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                finishRefresh();
            }

            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    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;
            }

            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
            }
        }
    }

AbstractApplicationContext 看起来就是一个快要成型的 ApplicationContext 了,这里 refresh() 方法看起来就是调用一些其他方法来做启动的。

2.3.1 AbstractApplicationContext#prepareRefresh

那首先就是准备环境:

    protected void prepareRefresh() {
        // Switch to active.
        this.startupDate = System.currentTimeMillis();
    // 设置非关闭状态
        this.closed.set(false);
    // 已激活状态
        this.active.set(true);

        if (logger.isDebugEnabled()) {
            if (logger.isTraceEnabled()) {
                logger.trace("Refreshing " + this);
            }
            else {
                logger.debug("Refreshing " + getDisplayName());
            }
        }

        // 这是一个空的方法,允许子类重写,做一些其他属性源的准备。
        initPropertySources();

        // 验证用户设置的必要的属性,如果这些属性确实则会抛出异常
    // 目前来说我没有设置任何必要的属性,所以这一步是空的实现
        getEnvironment().validateRequiredProperties();

        // 下面代码都是初始化 applicationListeners 的容器
    // 也就是 applicationContext 启动前我们注册的事件监听器
        if (this.earlyApplicationListeners == null) {
            this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
        }
        else {
            // Reset local application listeners to pre-refresh state.
            this.applicationListeners.clear();
            this.applicationListeners.addAll(this.earlyApplicationListeners);
        }

        // Allow for the collection of early ApplicationEvents,
        // to be published once the multicaster is available...
        this.earlyApplicationEvents = new LinkedHashSet<>();
    }

初始化我感觉没做什么特别的事情,也就是初始化一些必要的容器。

接下来就是大事情了:

// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

创建一个 BeanFactory

2.3.2 AbstractApplicationContext#obtainFreshBeanFactory

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
  refreshBeanFactory();
  return getBeanFactory();
}

protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;

public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;

好了,这就是一个模板方法的设计模式,调用了两个需要子类实现的方法。

《【Spring源码】一个我们日常接触的ApplicationContext》


接下来看看子类怎么创建的:

    @Override
    protected final void refreshBeanFactory() throws BeansException {
        if (hasBeanFactory()) {
            destroyBeans();
            closeBeanFactory();
        }
        try {
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            beanFactory.setSerializationId(getId());
            customizeBeanFactory(beanFactory);
            loadBeanDefinitions(beanFactory);
            synchronized (this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        }
        catch (IOException ex) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
        }
    }


    @Override
    public final ConfigurableListableBeanFactory getBeanFactory() {
        synchronized (this.beanFactoryMonitor) {
            if (this.beanFactory == null) {
                throw new IllegalStateException("BeanFactory not initialized or already closed - " +
                        "call 'refresh' before accessing beans via the ApplicationContext");
            }
            return this.beanFactory;
        }
    }

OK,我们现在看到,首先检测当前是否有工厂实例存在,如果有,直接清理掉里面的数据。然后创建、配置、并且返回回去。在子类看来就只有做这几件事情。

那在当前类的 refreshBeanFactory 方法中,就是着重的看着,是怎么配置并且构建的就 ok 了。

首先看 DefaultListableBeanFactory beanFactory = createBeanFactory(); 这个:

protected DefaultListableBeanFactory createBeanFactory() {
 return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}

好吧,过!

然后开始设置 SerializationId 这个也不需要看。

下一个是 customizeBeanFactory(beanFactory);

protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
 if (this.allowBeanDefinitionOverriding != null) {
  beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
 }
 if (this.allowCircularReferences != null) {
  beanFactory.setAllowCircularReferences(this.allowCircularReferences);
 }
}

这是两个自定义的属性,一个是是否允许覆盖 Bean 的定义,一个是是否允许相互依赖,但是这两个 this. 开头的都是 null,如果子类需要修改这两个值的话,则需要在子类调用相对应的 setter。因为没有调用,所以均使用 DefaultListableBeanFactory 默认设置的值:

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
        implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {

  /** Whether to allow re-registration of a different definition with the same name. */
    private boolean allowBeanDefinitionOverriding = true;

}

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
        implements AutowireCapableBeanFactory {

    /** Whether to automatically try to resolve circular references between beans. */
    private boolean allowCircularReferences = true;

}

然后开始读取配置,然而读取配置的实现也是需要留给子类去实现的:

loadBeanDefinitions(beanFactory);

protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
            throws BeansException, IOException;

@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
 // Create a new XmlBeanDefinitionReader for the given BeanFactory.
 XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

 // Configure the bean definition reader with this context's
 // resource loading environment.
 beanDefinitionReader.setEnvironment(this.getEnvironment());
 beanDefinitionReader.setResourceLoader(this);
 beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

 // Allow a subclass to provide custom initialization of the reader,
 // then proceed with actually loading the bean definitions.
 initBeanDefinitionReader(beanDefinitionReader);
 loadBeanDefinitions(beanDefinitionReader);
}

OK,子类要准备开始读取配置了。不过读取的实现和上一篇大同小异,我就不再重复了。

还记得我们刚刚在哪里吗,我们在 AbstractApplicationContext#refresh 进入了 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 这句话,接下来要进一步加工了。

2.3.3 AbstractApplicationContext#prepareBeanFactory

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
 // Tell the internal bean factory to use the context's class loader etc.
 beanFactory.setBeanClassLoader(getClassLoader());
 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

 // 注册事件回调
 beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
 // 实现这些接口的类不允许被注入
 // 他们的作用只是用来回调
 beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
 beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
 beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
 beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
 beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
 beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

 // 手动注册一些必要的接口的实现类,比如监听器,可以用于回调
 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
 beanFactory.registerResolvableDependency(ResourceLoader.class, this);
 beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
 beanFactory.registerResolvableDependency(ApplicationContext.class, this);

 // 内部类调用的事件回调
 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

 // 指定类在加载时织入AOP操作
 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()));
 }

 // 一些记录环境信息的Bean
 if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
  beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
 }
 if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
  beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
 }
 if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
  beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
 }
}

2.3.4 AbstractApplicationContext#postProcessBeanFactory

这个函数是留给子类实现,这时候 BeanFactory 中的 BeanDefinition 已经全部注册完毕,子类想删除新增或者其他操作都可以继续在这里实现。

2.3.5 AbstractApplicationContext#invokeBeanFactoryPostProcessors

来到这一步,说明 BeanFactory 一切准备就绪,这时候开始调用我们项目中注册到 BeanFactory 中的 BeanFactoryPostProcessors 处理器。

这一步呢,在我们项目中的应用就是,开始自动向权限中心注册当前项目中的用于管理数据的接口,以便项目更新即可分配新的权限。

2.3.6 AbstractApplicationContext#registerBeanPostProcessors

这一步是注册用户配置的实现 BeanPostProcessor 的实现类,用于监听每一个 Bean 实例化的前后所需要做的操作。

2.3.7 其他初始化

// 初始化i18n资源的转换接口
initMessageSource();

// 初始化当前Context的消息广播
initApplicationEventMulticaster();

// 子类可覆写的其他refresh事件
onRefresh();

// 检查、注册监听器
registerListeners();

// 初始化非 lazy-init 的 Bean,如果配置了 lazy-init=false 则
// 配置的 Bean 以及关联的 Bean 会在这个时候被初始化
finishBeanFactoryInitialization(beanFactory);

// 广播事件、清理初始化中的缓存
finishRefresh();

finally {
  // 清理初始化过程中用到的 Class 缓存
  resetCommonCaches();
}

2.4 初始化配置类配置的Bean

在上面我没有看到配置类配置的 Bean,因为我在 debug 的时候,前几步观察 BeanFactory 的情况,都没看到我注册的 MyBean,后面就跳过了。

然而我错了,我发现在 getBean 的时候,我的 MyBean 他居然已经准备好了,所以肯定是在上面某个环节偷偷给我注册进去了的。

所以我现在需要返回去看看是哪一步进入的。

通过观察,我发现是在 invokeBeanFactoryPostProcessors(beanFactory); 这句话之后发生了 BeanDefinitionMap 的长度变化。

所以现在要看这句话做了什么事情。

其实因为在我想象中,xml 属于一种解析方式,javaConfig 应该跟 xml 平行的属于另外一种,但是貌似完全不是。Spring 是通过 BeanFactoryPostProcessor 来处理的。也就是说 SpringBoot 他启动貌似不需要解析器?

OK,来看下这个方法做了什么事情:

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)
 if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
  beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
  beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
 }
}

下面那句话说了,是织入运行时处理器,那么肯定是在第一句话就做了注册的。继续进入观察。

getBeanFactoryPostProcessors() 在目前的状态,是一个空的集合,所以我们现在需要进入看看。

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

  // 因为我们目前没有任何的 beanFactoryPostProcessors 所以这个循环并不会进入。
  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.
  // 在这里不初始化 FactoryBeans 从而可以让 beanfactory 的 post-processors 来处理他们
  // 因为下面需要排序这些配置 Bean 的执行顺序。
  List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

  // 开始排序这些Bean的顺序
  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();

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

  /*
    // 循环所有的 postProcessors 开始调用。目前只有一个 BeanDefinitionRegistryPostProcessor
    // 是在 applicationContext 准备工作中加入的
    private static void invokeBeanDefinitionRegistryPostProcessors(
            Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {

        for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
            postProcessor.postProcessBeanDefinitionRegistry(registry);
        }
    }
  */

  currentRegistryProcessors.clear();

  /* 
    下面这些目前可以先不用看了。是用来执行其他 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();
  }

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

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

好我现在要在装配那部分开始进入了,因为 Spring 在开始的时候调用了 ConfigurationClassPostProcessorpostProcessBeanDefinitionRegistry 方法,现在要看看这个方法做了什么事情。

@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
 int registryId = System.identityHashCode(registry);
 if (this.registriesPostProcessed.contains(registryId)) {
  throw new IllegalStateException(
    "postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
 }
 if (this.factoriesPostProcessed.contains(registryId)) {
  throw new IllegalStateException(
    "postProcessBeanFactory already called on this post-processor against " + registry);
 }
 this.registriesPostProcessed.add(registryId);

 // 开始解析 ConfigBean 的内容
 processConfigBeanDefinitions(registry);
}

    public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
        List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
        String[] candidateNames = registry.getBeanDefinitionNames();

    // 开始拿 registry 中的所有 Bean 一顿循环。
        for (String beanName : candidateNames) {
            BeanDefinition beanDef = registry.getBeanDefinition(beanName);
            if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
                }
            }
      // 如果 Bean 定义上有 @Configuration 加入 configCandidates 集合中
            else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
                configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
            }
        }

        // Return immediately if no @Configuration classes were found
        if (configCandidates.isEmpty()) {
            return;
        }

        // 排序,但是目前这一步并不需要
        configCandidates.sort((bd1, bd2) -> {
            int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
            int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
            return Integer.compare(i1, i2);
        });

        // Detect any custom bean name generation strategy supplied through the enclosing application context
        SingletonBeanRegistry sbr = null;
        if (registry instanceof SingletonBeanRegistry) {
            sbr = (SingletonBeanRegistry) registry;
            if (!this.localBeanNameGeneratorSet) {
                BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
                        AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
                if (generator != null) {
                    this.componentScanBeanNameGenerator = generator;
                    this.importBeanNameGenerator = generator;
                }
            }
        }

        if (this.environment == null) {
            this.environment = new StandardEnvironment();
        }

        // 开始使用 ConfigurationClassParser 来解析配置类
        ConfigurationClassParser parser = new ConfigurationClassParser(
                this.metadataReaderFactory, this.problemReporter, this.environment,
                this.resourceLoader, this.componentScanBeanNameGenerator, registry);

        Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
        Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
        do {
            parser.parse(candidates);
            parser.validate();

            Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
            configClasses.removeAll(alreadyParsed);

            // 使用 ConfigurationClassBeanDefinitionReader 来解析配置类
      // 这一步就跟 xml reader 一样,解析里面各个标签
            if (this.reader == null) {
                this.reader = new ConfigurationClassBeanDefinitionReader(
                        registry, this.sourceExtractor, this.resourceLoader, this.environment,
                        this.importBeanNameGenerator, parser.getImportRegistry());
            }
            this.reader.loadBeanDefinitions(configClasses);
            alreadyParsed.addAll(configClasses);

            candidates.clear();
            if (registry.getBeanDefinitionCount() > candidateNames.length) {
                String[] newCandidateNames = registry.getBeanDefinitionNames();
                Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
                Set<String> alreadyParsedClasses = new HashSet<>();
                for (ConfigurationClass configurationClass : alreadyParsed) {
                    alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
                }
                for (String candidateName : newCandidateNames) {
                    if (!oldCandidateNames.contains(candidateName)) {
                        BeanDefinition bd = registry.getBeanDefinition(candidateName);
                        if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
                                !alreadyParsedClasses.contains(bd.getBeanClassName())) {
                            candidates.add(new BeanDefinitionHolder(bd, candidateName));
                        }
                    }
                }
                candidateNames = newCandidateNames;
            }
        }
        while (!candidates.isEmpty());

        // Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
        if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
            sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
        }

        if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
            // Clear cache in externally provided MetadataReaderFactory; this is a no-op
            // for a shared cache since it'll be cleared by the ApplicationContext.
            ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
        }
    }

首先看看 ConfigurationClassParser 是怎么解析配置的:

ConfigurationClassParser#parse
    public void parse(Set<BeanDefinitionHolder> configCandidates) {
        for (BeanDefinitionHolder holder : configCandidates) {
            BeanDefinition bd = holder.getBeanDefinition();
            try {
                if (bd instanceof AnnotatedBeanDefinition) {
                    parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
                }
                else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
                    parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
                }
                else {
          // 直接进入到这里解析(其实上面看起来就是强转之前的判断)
                    parse(bd.getBeanClassName(), holder.getBeanName());
                }
            }
            catch (BeanDefinitionStoreException ex) {
                throw ex;
            }
            catch (Throwable ex) {
                throw new BeanDefinitionStoreException(
                        "Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
            }
        }

        this.deferredImportSelectorHandler.process();
    }

parse 里边先根据环境,简单封装了配置类的信息以及其他的相关信息 MetadataReader

protected final void parse(@Nullable String className, String beanName) throws IOException {
 Assert.notNull(className, "No bean class name for configuration class bean definition");
 MetadataReader reader = this.metadataReaderFactory.getMetadataReader(className);
 processConfigurationClass(new ConfigurationClass(reader, beanName));
}
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
  if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
    return;
  }

  ConfigurationClass existingClass = this.configurationClasses.get(configClass);
  if (existingClass != null) {
    if (configClass.isImported()) {
      if (existingClass.isImported()) {
        existingClass.mergeImportedBy(configClass);
      }
      // Otherwise ignore new imported config class; existing non-imported class overrides it.
      return;
    }
    else {
      // Explicit bean definition found, probably replacing an import.
      // Let's remove the old one and go with the new one.
      this.configurationClasses.remove(configClass);
      this.knownSuperclasses.values().removeIf(configClass::equals);
    }
  }

  // 循环解析到父级 但是我们现在
  SourceClass sourceClass = asSourceClass(configClass);
  do {
    // 这里面解析了 @ComponentScan @Import 等注解,见下面,如果有父级,会返回父级,否则返回NULL
    sourceClass = doProcessConfigurationClass(configClass, sourceClass);
  }
  while (sourceClass != null);

  this.configurationClasses.put(configClass, configClass);
}
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
  throws IOException {

  if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
    // 解析内部类
    processMemberClasses(configClass, sourceClass);
  }

  // 解析配置类(SpringBoot 熟悉的写配置自动提示那种配置)
  for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
    sourceClass.getMetadata(), PropertySources.class,
    org.springframework.context.annotation.PropertySource.class)) {
    if (this.environment instanceof ConfigurableEnvironment) {
      processPropertySource(propertySource);
    }
    else {
      logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
                  "]. Reason: Environment must implement ConfigurableEnvironment");
    }
  }

  // 解析 @ComponentScan 这块打算后面再看了
  Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
    sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
  if (!componentScans.isEmpty() &&
      !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
    for (AnnotationAttributes componentScan : componentScans) {
      // The config class is annotated with @ComponentScan -> perform the scan immediately
      Set<BeanDefinitionHolder> scannedBeanDefinitions =
        this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
      // Check the set of scanned definitions for any further config classes and parse recursively if needed
      for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
        BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
        if (bdCand == null) {
          bdCand = holder.getBeanDefinition();
        }
        if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
          parse(bdCand.getBeanClassName(), holder.getBeanName());
        }
      }
    }
  }

  // 解析 @Import 注解
  processImports(configClass, sourceClass, getImports(sourceClass), true);

  // 解析 @ImportResource 注解
  AnnotationAttributes importResource =
    AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
  if (importResource != null) {
    String[] resources = importResource.getStringArray("locations");
    Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
    for (String resource : resources) {
      String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
      configClass.addImportedResource(resolvedResource, readerClass);
    }
  }

  // 解析 @Bean ,不过现在只是整理配置了 @Bean 的方法
  Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
  for (MethodMetadata methodMetadata : beanMethods) {
    configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
  }

  // Process default methods on interfaces
  processInterfaces(configClass, sourceClass);

  // Process superclass, if any
  if (sourceClass.getMetadata().hasSuperClass()) {
    String superclass = sourceClass.getMetadata().getSuperClassName();
    if (superclass != null && !superclass.startsWith("java") &&
        !this.knownSuperclasses.containsKey(superclass)) {
      this.knownSuperclasses.put(superclass, configClass);
      // Superclass found, return its annotation metadata and recurse
      return sourceClass.getSuperClass();
    }
  }

  // No superclass -> processing is complete
  return null;
}

可不可以这么说,在使用 JavaBean 进行配置的时候,Spring 做了一个能够解读里面每一句的意思的类编译器。

接下来,回到 ConfigurationClassPostProcessorprocessConfigBeanDefinitions 里边。调用了 parser.validate(); 主要验证 cglib 生成的配置类。

紧接着开始解析 this.reader.loadBeanDefinitions(configClasses);

public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
 // 我们知道,Configurator是可以增加条件判断的
 TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
 for (ConfigurationClass configClass : configurationModel) {
  // 开始读取 BeanDefinitions
  loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
 }
}
private void loadBeanDefinitionsForConfigurationClass(
  ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {

  // 如果条线显示,不需要启动此配置,则将其从 BeanFactory 中移除掉
  if (trackedConditionEvaluator.shouldSkip(configClass)) {
    String beanName = configClass.getBeanName();
    if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
      this.registry.removeBeanDefinition(beanName);
    }
    this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
    return;
  }

  if (configClass.isImported()) {
    registerBeanDefinitionForImportedConfigurationClass(configClass);
  }
  // 开始解析每个被 @Bean 修饰的方法
  for (BeanMethod beanMethod : configClass.getBeanMethods()) {
    loadBeanDefinitionsForBeanMethod(beanMethod);
  }

  // 读取完成后,读取其他资源
  loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
  loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
  ConfigurationClass configClass = beanMethod.getConfigurationClass();
  MethodMetadata metadata = beanMethod.getMetadata();
  String methodName = metadata.getMethodName();

  // 继续条件判断,判断是否需要创建 Bean
  if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) {
    configClass.skippedBeanMethods.add(methodName);
    return;
  }
  if (configClass.skippedBeanMethods.contains(methodName)) {
    return;
  }

  AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
  Assert.state(bean != null, "No @Bean annotation attributes");

  // Consider name and any aliases
  List<String> names = new ArrayList<>(Arrays.asList(bean.getStringArray("name")));
    // 这一步让我知道了,方法名就是 bean 的名字= =
  String beanName = (!names.isEmpty() ? names.remove(0) : methodName);

  // Register aliases even when overridden
  for (String alias : names) {
    this.registry.registerAlias(beanName, alias);
  }

  // 判断 xml 配置的 override 是否跟 JavaConfig 冲突了
  if (isOverriddenByExistingDefinition(beanMethod, beanName)) {
    if (beanName.equals(beanMethod.getConfigurationClass().getBeanName())) {
      throw new BeanDefinitionStoreException(beanMethod.getConfigurationClass().getResource().getDescription(),
                                             beanName, "Bean name derived from @Bean method '" + beanMethod.getMetadata().getMethodName() +
                                             "' clashes with bean name for containing configuration class; please make those names unique!");
    }
    return;
  }

  ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata);
  beanDef.setResource(configClass.getResource());
  beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));

  // 非 static 方法
  if (metadata.isStatic()) {
    // static @Bean method
    if (configClass.getMetadata() instanceof StandardAnnotationMetadata) {
      beanDef.setBeanClass(((StandardAnnotationMetadata) configClass.getMetadata()).getIntrospectedClass());
    }
    else {
      beanDef.setBeanClassName(configClass.getMetadata().getClassName());
    }
    beanDef.setUniqueFactoryMethodName(methodName);
  }
  else {
    // 我的配置被当成 FactoryBean 来处理了
    beanDef.setFactoryBeanName(configClass.getBeanName());
    beanDef.setUniqueFactoryMethodName(methodName);
  }

  if (metadata instanceof StandardMethodMetadata) {
    beanDef.setResolvedFactoryMethod(((StandardMethodMetadata) metadata).getIntrospectedMethod());
  }

  beanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
  beanDef.setAttribute(org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor.
                       SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);

  AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);

  // 开始解析一系列的属性
  Autowire autowire = bean.getEnum("autowire");
  if (autowire.isAutowire()) {
    beanDef.setAutowireMode(autowire.value());
  }

  boolean autowireCandidate = bean.getBoolean("autowireCandidate");
  if (!autowireCandidate) {
    beanDef.setAutowireCandidate(false);
  }

  String initMethodName = bean.getString("initMethod");
  if (StringUtils.hasText(initMethodName)) {
    beanDef.setInitMethodName(initMethodName);
  }

  String destroyMethodName = bean.getString("destroyMethod");
  beanDef.setDestroyMethodName(destroyMethodName);

  // Consider scoping
  ScopedProxyMode proxyMode = ScopedProxyMode.NO;
  AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(metadata, Scope.class);
  if (attributes != null) {
    beanDef.setScope(attributes.getString("value"));
    proxyMode = attributes.getEnum("proxyMode");
    if (proxyMode == ScopedProxyMode.DEFAULT) {
      proxyMode = ScopedProxyMode.NO;
    }
  }

  // Replace the original bean definition with the target one, if necessary
  BeanDefinition beanDefToRegister = beanDef;
  if (proxyMode != ScopedProxyMode.NO) {
    BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy(
      new BeanDefinitionHolder(beanDef, beanName), this.registry,
      proxyMode == ScopedProxyMode.TARGET_CLASS);
    beanDefToRegister = new ConfigurationClassBeanDefinition(
      (RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata);
  }

  if (logger.isTraceEnabled()) {
    logger.trace(String.format("Registering bean definition for @Bean method %s.%s()",
                               configClass.getMetadata().getClassName(), beanName));
  }

  // 好了,第一篇解析 xml 的时候已经说过了,复用了之前的方法
  this.registry.registerBeanDefinition(beanName, beanDefToRegister);
}

好了,现在回到上面刚刚的地方:

/* 
    下面这些目前可以先不用看了。是用来执行其他 BeanDefinitionRegistryPostProcessors
    因为我目前的主要点在于怎么解析我的配置类。
  */
  // 开始运行其他的 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);
   currentRegistryProcessors.clear();
  }

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

 // 然后按照,配置了 PriorityOrdered、配置了 Ordered、未配置顺序的执行顺序来执行这些生命周期回调函数
 // 其中使用了 processedBeans 来记录已经执行过的 processor,如果执行过的则会跳过
 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<>(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);

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

这串动作做好了以后,我们在 MyBeanConfiguration 里面配置的 MyBean.class,已经被注册到了当前的 BeanFactory 中去了。然后回到这里:

AbstractApplicationContext#refresh():
...
registerBeanPostProcessors(beanFactory);

// Initialize message source for this context.
initMessageSource();

// Initialize event multicaster for this context.
initApplicationEventMulticaster();

// Initialize other special beans in specific context subclasses.
onRefresh();

// Check for listener beans and register them.
registerListeners();

// 在这里实例化我们没有加上 @LazyInit 的对象,也就是 MyBean 在这里进行实例化
finishBeanFactoryInitialization(beanFactory);
...

2.5 初始化配置的Bean对象

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
 // 注册数据转换器
 if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
   beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
  beanFactory.setConversionService(
    beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
 }

 // 注册配置文件解析器,解析注入配置文件的那种方式
 if (!beanFactory.hasEmbeddedValueResolver()) {
  beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
 }

 // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
 // AOP相关的先跳过
 String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
 for (String weaverAwareName : weaverAwareNames) {
  getBean(weaverAwareName);
 }

 // Stop using the temporary ClassLoader for type matching.
 beanFactory.setTempClassLoader(null);

 // 缓存BeanDefinition的内容,这时候过后已经停止修改BeanDefinition的内容了
 beanFactory.freezeConfiguration();

 // 在这里做配置类中所有对象的初始化
 beanFactory.preInstantiateSingletons();
}

DefaultListableBeanFactory#preInstantiateSingletons
@Override
public void preInstantiateSingletons() throws BeansException {
  if (logger.isTraceEnabled()) {
    logger.trace("Pre-instantiating singletons in " + this);
  }

  // Iterate over a copy to allow for init methods which in turn register new bean definitions.
  // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
  List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

  // 便利所有非LazyInit的BeanNames,拿到BeanDefinition进行初始化。
  for (String beanName : beanNames) {
    RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
    if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
      if (isFactoryBean(beanName)) {
        Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
        if (bean instanceof FactoryBean) {
          final FactoryBean<?> factory = (FactoryBean<?>) bean;
          boolean isEagerInit;
          if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
            isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                                                        ((SmartFactoryBean<?>) factory)::isEagerInit,
                                                        getAccessControlContext());
          }
          else {
            isEagerInit = (factory instanceof SmartFactoryBean &&
                           ((SmartFactoryBean<?>) factory).isEagerInit());
          }
          if (isEagerInit) {
            getBean(beanName);
          }
        }
      }
      else {
        // 在这里触发初始化,进去后直接到AbstractBeanFactory#getBean
        // 已经很熟悉的函数了,不再细说。
        getBean(beanName);
      }
    }
  }

  // 触发post-initialization回调函数
  for (String beanName : beanNames) {
    Object singletonInstance = getSingleton(beanName);
    if (singletonInstance instanceof SmartInitializingSingleton) {
      final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
      if (System.getSecurityManager() != null) {
        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
          smartSingleton.afterSingletonsInstantiated();
          return null;
        }, getAccessControlContext());
      }
      else {
        smartSingleton.afterSingletonsInstantiated();
      }
    }
  }
}

点赞