通常我们在使用 Spring 容器的时候,只需要 new 一个 ApplicationContext 的子类即可使用,使用起来非常的简单,但是往往使用越简单的东西,其底层越复杂,本文通过从 new 一个 AnnotationConfigApplicationContext 类开始分析,看看 Spring 在启动的时候做了哪些工作。

AliasRegistry:支持别名功能,一个名字可以对应多个别名BeanDefinitionRegistry::可以注册、保存、移除、获取某个BeanDefinitionBeanFactory :Bean工厂,可以根据某个 Bean 的名字、或类型、或别名获取某个Bean对象SingletonBeanRegistry:单例 Bean 的注册,获取,判断是否存在,统计HierarchicalBeanFactory:父子容器的支持ListableBeanFactory:批量获取 Bean 的一系列接口ConfigurableBeanFactory:提供了 Bean 工厂的配置,如类加载器,类型转化,属性编辑器,作用域,添加 BeanPostProcessor 等功能我们通常所说的单例池其实就是定义在 DefaultListableBeanFactory 的一个成员变量 Map 集合里面,通过上面的类架构图可以看到 DefaultListableBeanFactory 间接或直接的实现了很多接口,由此可以看出这个实现类功能比较完备,所以我们一般使用 DefaultListableBeanFactory 来作为我们的容器使用。

MessageSource:国际化支援支持EnvironmentCapable:运行时环境变量获取ApplicationEventPublisher:事件发布与监听,实现组件之间的解耦ResourcePatternResolver:通配符方式获取一组 Resource 资源Lifecycle:容器生命周期接口通过对比 DefaultListableBeanFactory 和 AnnotationConfigApplicationContext 的类架构图,可以发现存在一些都实现的接口,比方说 BeanDefinitionRegistry,BeanFactory。还有 DefaultListableBeanFactory 和 AnnotationConfigApplicationContext 他们两个之间又是什么关系了?通过分析源码查看 AnnotationConfigApplicationContext 的父类 GenericApplicationContext:

我们可以看到在 GenericApplicationContext 类成员变量上持有一个 DefaultListableBeanFactory 的对象引用,并且在无参构造会创建这个 DefaultListableBeanFactory 类,由此我们可以得出结论,AnnotationConfigApplicationContext 和 DefaultListableBeanFactory 组合关系,虽然 AnnotationConfigApplicationContext 实现了 BeanDefinitionRegistry,BeanFactory 接口,但其实是委托 DefaultListableBeanFactory 去实现的。
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
在使用 Spring 容器的时候,通常从 new 一个 AnnotationConfigApplicationContext 类开始,并且会在通过构造函数传入一个 AppConfig 配置类,然后在这个配置类上加一个 @ComponentScan("com.demo1") 注解告诉 Spring 需要扫描的包路径。对应的构造函数如下:

可以看到,在 AnnotationConfigApplicationContext 的内部构造函数有三行代码分别做了如下动作:
AbstractApplicationContext 定义的接下来的 Spring 启动流程分析都是围绕这三个点来进行。

StartupStep 是 Spring 提供用监控统计每个操作节点的耗时,和一些处理数据的,这里我们可以忽略掉,不关心这个,主要关注创建 AnnotatedBeanDefinitionReader 对象和创建ClassPathBeanDefinitionScanner 对象这两行代码。
AnnotatedBeanDefinitionReader 此类的基本作用就是解析 class 为 BeanDefinition,然后注册到 BeanFactory中,当然构造器中也向 BeanFactory 中提前注册了一些内部后置处理器类用于之后的 bean 解析及实例化等操作。

在 AnnotatedBeanDefinitionReader 类有四个成员变量,分别用来帮助解析 class 注册成为 beanDefinition的,其中 beanNameGenerator 和 scopeMetadataResolver 默认的指定实现,而 conditionEvaluator 和 BeanDefinitionRegistry 是通过构造传递进来的。

重点观察AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); 这行代码,这里会注册一些默认提供的 PostProcessor 后置处理器,用来解析 Spring 提供的一些注解,方法实现如下。

这里我只截了一部分,具体更全面的可以去看源码。由此可以看出,我们一些常用的注解 @Configuration @ComponentScan @Autowired 都是这里将对应的处理类注册进去,以便后续去解析我们自定义的 Bean。
ClassPathBeanDefinitionScanner 主要扫描指定的包路径下的所有类,并经过includeFilters和excludeFilters的过滤将 class 对象解析成为 beanDefinition 并注册到容器。其实 ClassPathBeanDefinitionScanner 相较于 AnnotatedBeanDefinitionReader 的构造函数初始化就没有那么多的操作。

有一个稍微比较重要的点就是,在这里会去判断是否使用默认的过滤器,也是我们为什么给我们的 class 加一个 @Component 注解就能扫描注册成为一个 Bean 的关键点吧。

另外通过分析代码发现,Spring 额外提供支持 JSR 规范提供的一些注解,也就是说你使用 @ManagedBean 和 @Named 注解也可以注册成为 bean,但前提是你得引入这个依赖
<!-- https://mvnrepository.com/artifact/javax.inject/javax.inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
通过跟踪源码分析,在创建 AnnotationConfigApplicationContext(AppConfig.class) 的时候首先会去调用自身的无参构造函数,在这个无参构造函数会去创建两个类 AnnotatedBeanDefinitionReader 和 ClassPathBeanDefinitionScanner 这两个类,并且会把 AnnotationConfigApplicationContext 自身作为参数传递进去。AnnotatedBeanDefinitionReader 是用来将 class 对象解析成为 beanDefinition 并且注册到容器,并且还会添加一些 PostProcessor 后置处理器,比较重要的 ConfigurationClassPostProcessor AutowiredAnnotationBeanPostProcessor CommonAnnotationBeanPostProcessor 后置处理器都是在这里注册添加进容器的。ClassPathBeanDefinitionScanner 主要接受一组包路径,并扫描指定的包路径下的所有类,并根据 includeFilters 和 excludeFilters 来决定哪些类能成为 bean。

实际上 AnnotationConfigApplicationContext 并不具备解析配置类的功能,所以最终是委托给了我们前面无参构造创建的 AnnotatedBeanDefinitionReader 去解析配置类并注册,因为 componentClasses 参数是可变数组,意味着我们可以传入多个配置类,所以最终会遍历这个配置类数组,调用 AnnotatedBeanDefinitionReader 的 doRegisterBean 去解析,所以接下来重点分析 doRegisterBean 这个方法。

第一步,首先会将我们要注册的类,包装成一个AnnotatedGenericBeanDefinition类型的 BeanDefinition,方便获取注册类上的注解元数据信息。如何会去判断注册类上是否有Conditional注解,然后会获取注解的指定的Condition接口的matches进行条件匹配,来判断是否需要跳过注册该类。像 SpringBoot 的条件注解都是基于此扩展而来的,所以我们也可以实现自己的条件注解。源代码见:com.demo1
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Demo {
}
@Demo
@Configuration
@Conditional({MyCondition.class})
public class AppConfig {
}
public class MyCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 如果该配置类上有 @Demo 注解那么就跳过,不解析注册到容器
if (metadata.isAnnotated(Demo.class.getName())){
return false;
}
return true;
}
}
public class ConditionalDemo {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(AppConfig.class);
context.refresh();
}
}
在上面的代码中,我自定义了一个Demo注解,然后实现了Condition接口的matches方法,逻辑很简单,就是判断注册的类上是否有@Demo注解,如果有的话,就返回 FALSE,不进行注册。
第二步,如果外部参数有传Supplier接口实现类参数的话,这里会保存到注册类的 BeanDefinition 属性里。Supplier接口不是 Spring 里面的,是 JDK 提供的一个函数式接口,主要就是返回一个对象。如果你设置了这个属性的话,Spring 在创建 Bean 的时候会调用这个接口获取你创建的对象,使用你创建的对象作为 Bean 实例。

源代码见:com.demo2

可以看到,当我们在注册 Bean 的时候,如果你指定了注册类的 BeanDefinition的instanceSupplier属性的话,那么它就会调用你这个函数式接口获取对象,而不去自己帮你创建了。
第三步,会去解析你的注册类是否有指定 Scope 属性值,如果没有的话,默认就是单例

第四步,生成 beanName,如果指定了就使用你指定的,没有指定使用默认的


第五步,解析 @Lazy @Primary @DependsOn @Role @Description 注解,然后设置值到你注册类的BeanDefinition的属性上,以便后面使用。

第六步,会去解析 qualifiers 参数是否有传值,有的话遍历这个注解参数数组,挨个判断进行相应的赋值。


第七步,检查是否有传 customizers 参数,这个参数是数组,里面装的是BeanDefinitionCustomizer接口的实现类,会遍历数组,依次调用customize方法,会把当前正在处理的注册类的 BeanDefinition传给这个方法,让你在注册到容器前,还能做一些修改。

源代码见:com.demo3
@Scope(scopeName = "prototype")
public class CustomizerBean {
}
public class MyBeanDefinitionCustomizer implements BeanDefinitionCustomizer {
@Override
public void customize(BeanDefinition bd) {
bd.setScope("singleton");
}
}
public class BeanDefinitionCustomizerDemo {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
AnnotatedBeanDefinitionReader reader = context.getReader();
BeanDefinitionCustomizer[] beanDefinitionCustomizers = {new MyBeanDefinitionCustomizer()};
reader.registerBean(CustomizerBean.class,null,null,beanDefinitionCustomizers);
context.refresh();
System.out.println(context.getBean(CustomizerBean.class));
System.out.println(context.getBean(CustomizerBean.class));
System.out.println(context.getBean(CustomizerBean.class));
}
}
上面的代码,我定义CustomizerBean这个注册类为原型的,但是自己实现了MyBeanDefinitionCustomizer一个接口,在注册的时候,我把这个BeanDefinitionCustomizer实现类一起注册进去了,然后从容器获取了3次CustomizerBeanBean,结果如下:

可以看到此时CustomizerBean这个 Bean 的作用域范围变成单例的
在分析 ScopedProxyMode 之前,先来看一个例子,看完也许你就更能清楚 ScopedProxyMode 是用来干什么的,解决了什么事情。源代码见:com.demo4
@Scope(value = "prototype")
public class ScopedProxyBeanB {
}
@Scope("singleton")
public class ScopedProxyBeanA {
@Autowired
private ScopedProxyBeanB scopedProxyBeanB;
public void testScope(){
System.out.println(scopedProxyBeanB);
}
}
public class ScopedProxyDemo {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(ScopedProxyBeanA.class);
context.register(ScopedProxyBeanB.class);
context.refresh();
ScopedProxyBeanA beanA = context.getBean(ScopedProxyBeanA.class);
beanA.testScope();
beanA.testScope();
beanA.testScope();
}
}
上面的例子很简单,有两个 Bean,分别是 ScopedProxyBeanB 和 ScopedProxyBeanA , ScopedProxyBeanB 是原型即多例的,ScopedProxyBeanA 是单例的,在 ScopedProxyBeanA 依赖注入了 ScopedProxyBeanB ,然后在 Main 方法调用了三次ScopedProxyBeanA的 testScope() 方法,结果如下:

可以看到,因为 ScopedProxyBeanA 是单例的,ScopedProxyBeanB 好像也变成单例的了,这是因为对于单例 Bean,Spring 只会对属性进行以此注入,所以就变成了上面的这种结果,这肯定不是我们所期望的结果,我们希望每次使用 ScopedProxyBeanB这个原型 Bean 的时候,每次使用都获取一个新的。
这时候就轮到 ScopedProxyMode 登场了,ScopedProxyMode 就是用来解决这个问题的,只需要在 ScopedProxyBeanB 的 @Scope 注解有一个属性 ScopedProxyMode 指定为代理即可,代码如下:
@Scope(value = "prototype",proxyMode = ScopedProxyMode.TARGET_CLASS)
public class ScopedProxyBeanB {
}
此时我们再执行这个 Main 方法,可以看到每次调用 testScope() 方法都获取到的是一个新的对象
com.demo4.ScopedProxyBeanB@3911c2a7
com.demo4.ScopedProxyBeanB@4ac3c60d
com.demo4.ScopedProxyBeanB@4facf68f
public enum ScopedProxyMode {
DEFAULT,
NO,
INTERFACES,
TARGET_CLASS
}
ScopedProxyMode 是一个枚举类型,其中 DEFAULT 和 NO 是等价的即不使用代理,INTERFACES 使用 JDK 动态代理,TARGET_CLASS 使用 CgLiB 动态代理,其底层实现原理就是基于动态代理,拦截你的所有方法,然后再拦截的逻辑里,每次都去重新去获取一遍对象,再将获取到的对象,帮你调用方法。
这一步主要分析了,在容器刷新之前,我们可以手动调用 register 方法注册一些配置类进去,会通过 AnnotatedBeanDefinitionReader 帮我们解析注册的配置类,然后封装成 BeanDefinition ,以便在接下来的 refresh 方法去解析这些 BeanDefinition,创建成为真正能为我们使用的 Bean 实例。
refresh 方法是在 AbstractApplicationContext.java 定义的,Spring 的各种容器都是基于此扩展而来的,而 refresh 方法是一个典型的模板方法设计模式的体现,在不同的操作节点上都有提供给子类扩展的点,而且 refresh 方法定义了容器初始化的一套完整的顺序流程,规则了先做什么,后做什么。接下来就主要分析 refresh 方法多做了那些操作,又有那些扩展点可以供我们扩展。

第一步,prepareRefresh 主要做一些刷新前的准备工作,设置Spring容器的启动时间,将容器的状态设置活跃状态,并调用了一个 initPropertySources 方法,这个方法在自身是空实现的,主要留给子类做扩展,可以加载一些子类独有的环境变量到容器内,最后检查一些必须存在的环境变量是否有缺少且可可解析的。

第二步,获取一个可用的容器,作为接下来注册的 Bean 和 BeanDefinition的容器,点进去看 obtainFreshBeanFactory ,代码如下:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
refreshBeanFactory() 在自身类是一个抽象方法,由子类去实现的,总共有两个类实现了这个方法,以下是 AbstractRefreshableApplicationContext 的实现

以下是 GenericApplicationContext 的实现

通过对比发现 GenericApplicationContext 是不支持重复刷新的,而 AbstractRefreshableApplicationContext 支持重复刷新,每次刷新都会判断是否存在旧的容器,如果存在则会先将旧的容器关闭,然后创建一个新的容器。
第三步,会将在第二步获取到的容器,传入这个方法,然后在方法里面注册一些预先定义的类到容器里面,具体实现代码如下:
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 设置 beanFactory 的类加载器
beanFactory.setBeanClassLoader(getClassLoader());
if (!shouldIgnoreSpel) {
// 注册 SPEL 表达式解析支持
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
// 为beanFactory增加一个默认的propertyEditor,这个主要是对bean的属性等设置管理一个工具
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 注册 ApplicationContextAwareProcessor bean后置处理器
// 主要用来处理 Aware 接口回调
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 当你实现了这些 Aware 接口回调,但是如果你的注入类型是 byType 或者 ByName 可以防止避免调用两次
// 因为在进行注入的时候会去这个列表判断,是否存在有对应的接口实现,如果有就不需要重复注入了
// 但是对应使用@Autowired注入是不生效的,还是会注入两次
// 源代码见:com.demo5
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.ignoreDependencyInterface(ApplicationStartupAware.class);
//注册可以解析的自动装配;我们能直接在任何组件中自动注入:
// BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext,实际获取到的都是这个容器本身
//其他组件中可以通过 @autowired 直接注册使用
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 注册 ApplicationListenerDetector bean后置处理器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 如果使用的不是 GraalVM虚拟机 且容器中有名称为loadTimeWeaver的beanDefinition
if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
// LoadTimeWeaverAwareProcessor 是一个bean 后置处理器
// 用来判断某个Bean是不是实现了LoadTimeWeaverAware接口,
// 如果实现了则把ApplicationContext中的loadTimeWeaver回调setLoadTimeWeaver方法设置给该Bean。
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// 检查是否有注册环境变量对象到单例池,如果没有则注册
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());
}
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
}
}
第四步,这也是一个抽象方法,留给子类扩展的,并且将当前的 BeanFactory 容器传进去了。比方说 Web 容器的子类会在这个方法里注册一个 ServletContextAwareProcessor Bean 后置处理器,用来处理 ServletContextAware 回调。

第五步,这一步就比较重要了,在这里回调所有的BeanFactoryPostProcessors Bean 工厂后置处理器的 postProcessBeanDefinitionRegistry 和 postProcessBeanFactory 方法。还记得前面在实例化 AnnotatedBeanDefinitionReader 对象时,向容器注册添加了一个 ConfigurationClassPostProcessor 的 Bean 工厂后置处理器吗?在这里会依次回调 ConfigurationClassPostProcessor 这个Bean 工厂后置处理器的 postProcessBeanDefinitionRegistry 和 postProcessBeanFactory 方法,而 postProcessBeanDefinitionRegistry 方法就会去拿到当前容器内所有的 BeanDefinition,并它们当做配置类去解析,ConfigurationClassPostProcessor 能够解析的注解有:@Configuration @Component @ComponentScan @ComponentScans @Import @ImportResource @Bean @PropertySources @PropertySource,还会去解析当前解析到的配置类的,父类是否也有对应的注解,比方说通过 @ComponentScan 注解的包路径扫描解析到一些类,那么这些类又有可能是配置类,那么就会递归去解析,以下是ConfigurationClassPostProcessor 解析过程:

当然我们也可以自己实现一个 Bean 工厂后置处理器,然后在这个时候往容器注册进 BeanDefinition,甚至可以在这里实例化一些单例 Bean 注册进容器。执行完 invokeBeanFactoryPostProcessors 这个方法后,基本我们所定义的 Bean 都已经被解析注册成为 BeanDefinition 了。
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// 存放所有的 BeanFactoryPostProcessor beanName
Set<String> processedBeans = new HashSet<>();
// 判断容器是否支持注册 beanDefinition
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 第一先执行外部参数传递 FactoryPostProcessors 的 postProcessBeanDefinitionRegistry,如果有的话
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
// 当前正在遍历执行的 BeanDefinitionRegistryPostProcessor 集合
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// 第二执行实现了 PriorityOrdered接口,并按PriorityOrdered接口排序执行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());
currentRegistryProcessors.clear();
// 第三执行实现了 Ordered接口,并按Ordered接口排序执行postProcessBeanDefinitionRegistry方法
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, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
// 第四执行没有实现 Ordered接口和PriorityOrdered接口的postProcessBeanDefinitionRegistry方法
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();
}
// 回调所有找到的 bean工厂后置处理器的 postProcessBeanFactory 方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// 如果不支持注册beanDefinition的话,就遍历参数beanFactoryPostProcessors的所有postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// 获取所有 BeanFactoryPostProcessor 的 beanName
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// 将 BeanFactoryPostProcessor 分为三组,实现了PriorityOrdered接口,Ordered接口,都没有实现的
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);
}
}
// 先执行PriorityOrdered接口并且排序执行postProcessBeanFactory方法
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 再执行Ordered接口并且排序执行postProcessBeanFactory方法
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// 最后执行没有实现Ordered接口和PriorityOrdered接口的postProcessBeanFactory方法
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();
}
第六步,在第五步我们已经扫描解析完了所有的 class 包装成 BeanDefinition 注册到容器内了,这其中就有可能包括一些 Bean 后置处理器,所以我们需要在实例化单例 Bean 之前,先把这个些 Bean 后置处理器提前创建好放入容器,所以这一步主要是将 Bean 后置处理器创建出来放到容器内。
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 获取所有的 BeanPostProcessor 对应的 beanName
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));
// 将 BeanPostProcessor 按照 PriorityOrdered接口,Ordered接口,和没时间排序接口分开处理
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// 存放实现了 MergedBeanDefinitionPostProcessor接口的 BeanPostProcessor
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)) {
// 创建实现了 PriorityOrdered接口的 bean后置处理器对象
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
// 如果实现了Ordered接口的 bean后置处理器,只是把其名字添加进了集合,这里并未创建其对象
orderedPostProcessorNames.add(ppName);
}
else {
// 未创建 bean后置处理器的实例
nonOrderedPostProcessorNames.add(ppName);
}
}
// 第一次先注册实现了 PriorityOrdered接口 bean后置处理器
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 第二注册实现了 Ordered接口的 bean后置处理器,并创建其对象
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);
// 第三注册实现了 没有实现排序接口的 bean后置处理器,并创建其对象
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);
// 对实现了 MergedBeanDefinitionPostProcessor 接口的 bean后置处理器进行重新排序
sortPostProcessors(internalPostProcessors, beanFactory);
// 重新注册进容器
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// 重新注册 ApplicationListenerDetector bean后置处理器,放置BeanPostProcessor集合最尾部
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
第七步,主要是判断容器内是否有 messageSource 这个 Bean ,如果没有就创建一个默认的然后注册到容器内,注意这里注册的不是 BeanDefinition,而是直接注册到单例池成为单例 Bean。
第八步,也是判断容器内是否有 applicationEventMulticaster 这个 Bean,如果有就从容器获取出来,并且赋值到自身的 applicationEventMulticaster 属性上,反之创建一个默认的注册到容器。
第九步,自身是空实现的方法,留个子类扩展的,一般 Web 容器会在这里初始化 ThemeSource。
第十步,主要将容器的监听者找出来,放到事件发布器助手 applicationEventMulticaster 保存管理,主要这里仅仅是将 BeanName 保存了,并未保存对象的引用,因为此时单例 Bean 尚未实例化。
protected void registerListeners() {
// 先检查容器内是否有预先定义的好的 ApplicationListener
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// 获取所有实现了 ApplicationListener 接口的 beanDefinition,但是如果是用 FactoryBean 包装的话,不会在这里获取到
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// 检查 earlyApplicationEvents 是否有监听者
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
第十一步,初始化所有非懒加载的单例 bean。关于 Bean 的创建和生命周期相关请参考我的另一篇文章。从源码角度分析Bean的创建过程
第十二步,发布容器刷新完成事件
第十三步,当在刷新容器的过程中出现了异常,会走到 catch 块处理
catch (BeansException ex) {
// 销毁所有的单例bean
destroyBeans();
// 重新设置容器的活动标记
cancelRefresh(ex);
// 将捕获到的异常抛出去
throw ex;
}
第十四步,清除容器使用过程中的一些缓存数据。
通过分析 refresh 方法,可以看到 Spring 在启动的时候都做了那些工作。
prepareRefresh 这一步创建和准备了 Environment 对象,它作为 ApplicationContext 的一个成员变量,Environment 对象的作用之一是为后续 @Value,值注入时提供键值。Environment 分成三个主要部分,systemProperties - 保存 java 环境键值,systemEnvironment - 保存系统环境键值,自定义 PropertySource - 保存自定义键值,例如来自于 *.properties 文件的键值。obtainFreshBeanFactory 创建或获取BeanFactory,它也是作为 ApplicationContext 的一个成员变量,另外还由子类定义是否允许重复刷新容器。prepareBeanFactory 这一步会进一步完善 BeanFactory,为它的各项成员变量赋值,注册了 StandardBeanExpressionResolver 支持 SPEL 表达式的解析,ResourceEditorRegistrar 类型转换器,注册ApplicationContextAwareProcessor 用来解析 Aware 接口,注册 ApplicationListenerDetector 用来识别容器中 ApplicationListener 类型的 bean。postProcessBeanFactory 空实现,留给子类扩展的,一般 Web 环境的 ApplicationContext 都要利用它注册新的 Scope,完善 Web 下的 BeanFactory。invokeBeanFactoryPostProcessors 回调容器内所有的 BeanFactoryPostProcessors 通常可以会在这里解析我们定义的配置类,以便获取更多的 BeanDefinition。registerBeanPostProcessors 找到容器内所有BeanPostProcessors 类型的 BeanDefinition,并在这里实例化,注册到容器内,AutowiredAnnotationBeanPostProcessor 功能有:解析 @Autowired,@Value 注解,CommonAnnotationBeanPostProcessor 功能有:解析 @Resource,@PostConstruct,@PreDestroy,AnnotationAwareAspectJAutoProxyCreator 功能有:为符合切点的目标 bean 自动创建代理。initMessageSource 这一步是为 ApplicationContext 添加 messageSource 成员,实现国际化功能。initApplicationEventMulticaster 这一步为ApplicationContext 添加事件广播器成员,即 applicationContextEventMulticaster 它的作用是发布事件给监听器。onRefresh 这一步是空实现,留给子类扩展registerListeners 这一步会从多种途径找到事件监听器,并添加至 applicationEventMulticaster,事件监听器顾名思义,用来接收事件广播器发布的事件,有如下来源:手动注入的,来自容器中的 bean 实现了 ApplicationListener 接口,来自于 @EventListener 的解析。finishBeanFactoryInitialization 初始化所有非延迟单例 bean。finishRefresh 这一步会为 ApplicationContext 添加 lifecycleProcessor 成员,用来控制容器内需要生命周期管理的 bean,如果容器中有名称为 lifecycleProcessor 的 bean 就用它,否则创建默认的生命周期管理器,然后发布 ContextRefreshed 事件,整个 refresh 执行完成。