Spring启动流程

3/25/2022 Spring源码分析

# Spring启动流程

img

# 1. Demo创建

  • Demo代码十分简单,整个工程结构如下:

img

  • pom依赖
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.8.RELEASE</version>
</dependency>
  • service包下的两个类OrderServiceUserService只加了@Service注解,dao包下的两个类OrderDaoUserDao只加了@Repository注解。MainApplication类中只写main()方法。代码如下:
public static void main(String[] args) {
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

    UserService userService = applicationContext.getBean(UserService.class);
    System.out.println(userService);

    OrderService orderService = applicationContext.getBean(OrderService.class);
    System.out.println(orderService);

    UserDao userDao = applicationContext.getBean(UserDao.class);
    System.out.println(userDao);

    OrderDao orderDao = applicationContext.getBean(OrderDao.class);
    System.out.println(orderDao);

    applicationContext.close();
}
  • AppConfig类是一个配置类,类上加了两个注解,加@Configuration表明AppConfig是一个配置类,加@ComponentScan是为了告诉Spring要扫描哪些包,代码如下:
@Configuration
@ComponentScan("com.tiantang.study")
	public class AppConfig {
}

# 2. 启动

运行MainApplication中的main()方法,这样一个Spring容器就运行起来了。控制台分别打印出了UserServiceOrderServiceUserDaoOrderDaohash码。

那么问题来了,相比以往xml配置的方式,现在就这么几行简单的代码,一个Spring容器就能运行起来,我们就能从容器中获取到BeanSpring内部是如何做到的呢?下面就来逐步分析Spring启动的源码。

# 3. 入口

程序的入口为main()方法,从代码中可以发现,核心代码只有一行,new AnnotationConfigApplicationContext(AppConfig.class),通过这一行代码,就将Spring容器给创建完成,然后我们就能通过getBean()从容器中获取到对象的了。因此,分析Spring源码,就从AnnotationConfigApplicationContext的有参构造函数开始。

AnnotationConfigApplicationContextClassPathXmlApplicationContext作用一样,前者对应的是采用JavaConfig技术的应用,后者对应的是XML配置的应用

# 4. 基础概念

在进行Spring源码阅读之前,需要先理解几个概念。

  1. Spring会将所有交由Spring管理的类,扫描其class文件,将其解析成**BeanDefinition**,在BeanDefinition中会描述类的信息,例如:这个类是否是单例的,Bean的类型,是否是懒加载,依赖哪些类,自动装配的模型。**Spring**创建对象时,就是根据**BeanDefinition**中的信息来创建**Bean**

  2. Spring容器在本文可以简单理解为**DefaultListableBeanFactory**,它是BeanFactory的实现类,这个类有几个非常重要的属性:beanDefinitionMap是一个map,用来存放bean所对应的BeanDefinitionbeanDefinitionNames是一个List集合,用来存放所有beannamesingletonObjects是一个Map,用来存放所有创建好的单例Bean

  3. Spring中有很多后置处理器,但最终可以分为两种,一种是BeanFactoryPostProcessor,一种是BeanPostProcessor前者的用途是用来干预**BeanFactory**的创建过程,后者是用来干预**Bean**的创建过程。后置处理器的作用十分重要,**bean**的创建以及**AOP**的实现全部依赖后置处理器。

# 5. AnnotationConfigApplicationContext的构造方法

AnnotationConfigApplicationContext的构造函数的参数,是一个可变数组,可以传多个配置类,在本次Demo中,只传了AppConfig一个类。

在构造函数中,会先调用this(),在this()中通过调用父类构造器初始化了BeanFactory,以及向容器中注册了7个后置处理器。然后调用register(),将构造方法的参数放入到BeanDefinitionMap中。最后执行refresh()方法,这是整个Spring容器启动的核心,本文也将重点分析refresh()方法的流程和作用。

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
    // 会初始化一个BeanFactory,为默认的DefaultListableBeanFactory
    // 会初始化一个beanDefinition的读取器,同时向容器中注册了7个spring的后置处理器(包括BeanPostProcessor和BeanFactoryPostProcessor)
    // 会初始化一个扫描器,后面似乎并没有用到这个扫描器,在refresh()中使用的是重新new的一个扫描器。
    this();
    // 将配置类注册进BeanDefinitionMap中
    register(annotatedClasses);
    refresh();
}
# 5.1 this()调用

this()会调用AnnotationConfigApplicationContext无参构造方法,而在Java的继承中,会先调用父类的构造方法。所以会先调用AnnotationConfigApplicationContext的父类GeniricApplicationContext的构造方法,在父类中初始化beanFactory,即直接new了一个DefaultListableBeanFactory

public GenericApplicationContext() {
    this.beanFactory = new DefaultListableBeanFactory();
}

this()中通过new AnnotatedBeanDefinitionReader(this)实例化了一个Bean读取器,并向BeanDefinitionMap中添加了7个元素。通过new ClassPathBeanDefinitionScanner(this)实例化了一个扫描器(该扫描器在后面并没有用到)。

public AnnotationConfigApplicationContext() {
    // 此处会先调用父类的构造器,即先执行 super(),初始化DefaultListableBeanFactory
    // 初始化了bean的读取器,并向spring中注册了7个spring自带的类,这里的注册指的是将这7个类对应的BeanDefinition放入到到BeanDefinitionMap中
    this.reader = new AnnotatedBeanDefinitionReader(this);
    // 初始化扫描器
    this.scanner = new ClassPathBeanDefinitionScanner(this);
}

执行this.reader = new AnnotatesBeanDefinitionReader(this)时,最后会调用到AnnotationConfigUtils.registerAnnotationConfigProcessors(BeanDefinitionRegistry registry,Object source)方法,这个方法向BeanDefinitionMap中添加了7个类,这7个类的BeanDefinition(关于BeanDefinition的介绍可以参考前面的解释)均为RootBeanDefinition,这几个类分别为ConfigurationClassPostProcessorAutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessorRequiredAnnotationBeanPostProcessorPersistenceBeanPostProcessorEventListenerMethodProcessorDefaultEventListenerFactory

这7个类中,ConfigurationClassPostProcessorAutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor这三个类非常重要,这里先在下面代码中简单介绍了一下作用,后面会单独写文章分析它们的作用。本文的侧重点是先介绍完Spring启动的流程。

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
            BeanDefinitionRegistry registry, @Nullable Object source) {
    DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
    // 省略部分代码 ...
    Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
    // 注册ConfigurationClassPostProcessor,这个类超级重要,它完成了对加了Configuration注解类的解析,@ComponentScan、@Import的解析。
    if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
    }
    // 注册AutowiredAnnotationBeanPostProcessor,这个bean的后置处理器用来处理@Autowired的注入
    if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
    }
    // 注册RequiredAnnotationBeanPostProcessor
    if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
    }
    // 注册CommonAnnotationBeanPostProcessor,用来处理如@Resource,@PostConstruct等符合JSR-250规范的注解
    // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
    if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
    }
    // 注册PersistenceAnnotationBeanPostProcessor,用来支持JPA
    // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
    if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition();
        try {
            def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
                    AnnotationConfigUtils.class.getClassLoader()));
        }
        catch (ClassNotFoundException ex) {
            throw new IllegalStateException(
                    "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
        }
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // 注册EventListenerMethodProcessor,用来处理方法上加了@EventListener注解的方法
    if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
    }

    // 注册DefaultEventListenerFactory,暂时不知道干啥用的,从类名来看,是一个事件监听器的工厂
    if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
    }
    return beanDefs;
}

调用this.scanner = new ClassPathBeanDefinitionScanner(this)来初始化一个扫描器,这个扫描器在后面扫描包的时候,并没有用到,猜测是Spring为了满足其他的场景而初始化的,例如: 开发人员手动通过register(configClass)时,扫描包时使用的。

# 5.2 register(annotatedClasses)

将传入的配置类annotatedClasses解析成BeanDefinition(实际类型为AnnotatedGenericBeanDefinition),然后放入到BeanDefinitionMap中,这样后面在ConfigurationClassPostProcessor中能解析annotatedClasses,例如demo中的AppConfig类,只有解析了**AppConfig**类,才能知道**Spring**要扫描哪些包(因为在**AppConfig**类中添加了**@ComponentScan**注解),只有知道要扫描哪些包了,才能扫描出需要交给**Spring**管理的**bean**有哪些,这样才能利用**Spring**来创建**bean**

# 5.3 执行refresh()方法

refresh()方法是整个Spring容器的核心,在这个方法中进行了bean的实例化、初始化、自动装配、AOP等功能。下面先看看refresh()方法的代码,代码中加了部分个人的理解,简单介绍了每一行代码作用,后面会针对几个重要的方法做出详细分析

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // Prepare this context for refreshing.
        // 初始化属性配置文件、检验必须属性以及监听器
        prepareRefresh();
        // Tell the subclass to refresh the internal bean factory.
        // 给beanFactory设置序列化id
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        // 向beanFactory中注册了两个BeanPostProcessor,以及三个和环境相关的bean
        // 这两个后置处理器为ApplicationContextAwareProcessor和ApplicationListenerDetector
        // 前一个后置处理是为实现了ApplicationContextAware接口的类,回调setApplicationContext()方法,
        // 后一个处理器时用来检测ApplicationListener类的,当某个Bean实现了ApplicationListener接口的bean被创建好后,会被加入到监听器列表中
        prepareBeanFactory(beanFactory);
        try {
            // Allows post-processing of the bean factory in context subclasses.
            // 空方法,由子类实现
            postProcessBeanFactory(beanFactory);
            // 执行所有的BeanFactoryPostProcessor,包括自定义的,以及spring内置的。默认情况下,容器中只有一个BeanFactoryPostProcessor,即:Spring内置的,ConfigurationClassPostProcessor(这个类很重要)
            // 会先执行实现了BeanDefinitionRegistryPostProcessor接口的类,然后执行BeanFactoryPostProcessor的类
            // ConfigurationClassPostProcessor类的postProcessorBeanFactory()方法进行了@Configuration类的解析,@ComponentScan的扫描,以及@Import注解的处理
            // 经过这一步以后,会将所有交由spring管理的bean所对应的BeanDefinition放入到beanFactory的beanDefinitionMap中
            // 同时ConfigurationClassPostProcessor类的postProcessorBeanFactory()方法执行完后,向容器中添加了一个后置处理器————ImportAwareBeanPostProcessor
            invokeBeanFactoryPostProcessors(beanFactory);
            // 注册所有的BeanPostProcessor,因为在方法里面调用了getBean()方法,所以在这一步,实际上已经将所有的BeanPostProcessor实例化了
            // 为什么要在这一步就将BeanPostProcessor实例化呢?因为后面要实例化bean,
            // 而BeanPostProcessor是用来干预bean的创建过程的,所以必须在bean实例化之前就实例化所有的BeanPostProcessor(包括开发人员自己定义的)
            // 最后再重新注册了ApplicationListenerDetector,这样做的目的是为了将ApplicationListenerDetector放入到后置处理器的最末端
            registerBeanPostProcessors(beanFactory);
            // Initialize message source for this context.
            // 初始化MessageSource,用来做消息国际化。在一般项目中不会用到消息国际化
            initMessageSource();
            // Initialize event multicaster for this context.
            // 初始化事件广播器,如果容器中存在了名字为applicationEventMulticaster的广播器,则使用该广播器
            // 如果没有,则初始化一个SimpleApplicationEventMulticaster
            // 事件广播器的用途是,发布事件,并且为所发布的时间找到对应的事件监听器。
            initApplicationEventMulticaster();

            // Initialize other special beans in specific context subclasses.
            // 执行其他的初始化操作,例如和SpringMVC整合时,需要初始化一些其他的bean,但是对于纯spring工程来说,onFresh方法是一个空方法
            onRefresh();

            // Check for listener beans and register them.
            // 这一步会将自定义的listener的bean名称放入到事件广播器中
            // 同时还会将早期的ApplicationEvent发布(对于单独的spring工程来说,在此时不会有任何ApplicationEvent发布,但是和springMVC整合时,springMVC会执行onRefresh()方法,在这里会发布事件)
            registerListeners();
            // 实例化剩余的非懒加载的单例bean(注意:剩余、非懒加载、单例)
            // 为什么说是剩余呢?如果开发人员自定义了BeanPosrProcessor,而BeanPostProcessor在前面已经实例化了,所以在这里不会再实例化,因此这里使用剩余一词
            finishBeanFactoryInitialization(beanFactory);
            // 结束refresh,主要干了一件事,就是发布一个事件ContextRefreshEvent,通知大家spring容器refresh结束了。
            finishRefresh();
        }
        catch (BeansException ex) {
            // 出异常后销毁bean
            destroyBeans();
            // Reset 'active' flag.
            cancelRefresh(ex);
            // Propagate exception to caller.
            throw ex;
        }
        finally {
           // 在bean的实例化过程中,会缓存很多信息,例如bean的注解信息,但是当单例bean实例化完成后,这些缓存信息已经不会再使用了,所以可以释放这些内存资源了
            resetCommonCaches();
        }
    }
}

# 6. refresh()方法

refresh()方法中,比较重要的方法为invokeBeanFactoryPostProcessors(beanFactory)finishBeanFactoryInitialization(beanFactory)。其他的方法相对而言比较简单,下面主要分析这两个方法,其他方法的作用,可以参考上面源码中的注释。

# 6.1 invokeBeanFactoryPostProcessors()

该方法的作用是执行所有的BeanFactoryPostProcessor,由于Spring会内置一个BeanFactoryPostProcessor,即ConfigurationClassPostProcessor(如果开发人员不自定义,默认情况下只有这一个BeanFactoryPostProcessor),这个后置处理器在处理时,会解析出所有交由**Spring**容器管理的**Bean**,将它们解析成**BeanDefinition**,然后放入到**BeanFactory****BeanDefinitionMap**中。

该方法最终会调用到PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()方法,主要作用是执行所有BeanFactoryPostProcessorpostProcessorBeanFactory()方法。BeanFactoryPostProcessor又分为两种情况,一种是直接实现BeanFactoryPostProcessor接口的类,另一种情况是实现了BeanDefinitionRegistryPostProcessor接口(BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor接口)。

img

在执行过程中先执行所有的BeanDefinitionRegistryPostProcessorpostProcessorBeanDefinitionRegistry()方法,然后再执行BeanFacotryPostProcessorpostProcessorBeanFactory()方法。

public interface BeanFactoryPostProcessor {
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
    void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}

默认情况下,Spring有一个内置的BeanFactoryPostProcessor,即:ConfigurationClassPostProcessor类,该类实现了BeanDefinitionRegistryPostProcessor类,所以会执行ConfigurationClassPostProcessor.postProcessorBeanDefinitionRegistry,ConfigurationClassPostProcessorUML图如上(删减了部分不重要的继承关系)

# 6.2 registerBeanPostProcessors()

该方法的作用是找到所有的**BeanPostProcessor**,然后将这些**BeanPostProcessor**实例化(会调用**getBean()**方法,**getBean()**方法的主要逻辑是,如果**bean**存在于**BeanFactory**中,则返回**bean****;如果不存在,则会去创建。**在后面会仔细分析getBean()的执行逻辑)。将这些PostProcessor实例化后,最后放入到BeanFactorybeanPostProcessors属性中。

问题:如何找到所有的BeanPostProcessor? 包括Spring内置的和开发人员自定义的。

由于在refresh()方法中,会先执行完invokeBeanFactoryPostProcessor()方法,这样所有自定义的BeanPostProcessor类均已经被扫描出并解析成BeanDefinition(扫描和解析又是谁做的呢?ConfigurationClassPostProcessor做的),存入至BeanFactoryBeanDefinitionMap,所以这儿能通过方法如下一行代码找出所有的BeanPostProcessor,然后通过getBean()全部实例化,最后再将实例化后的对象加入到BeanFactorybeanPostProcessors属性中,该属性是一个List集合。

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

最后再重新注册了ApplicationListenerDetector,这样做的目的是为了将ApplicationListenerDetector放入到后置处理器的最末端

registerBeanPostProcessor() 最终调用的是PostProcessorRegistrationDelegate.registerBeanPostProcessors(),下面是PostProcessorRegistrationDelegate.registerBeanPostProcessors()方法的代码

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

    // 从BeanDefinitionMap中找出所有的BeanPostProcessor
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
    // ... 省略部分代码 ...

    // 分别找出实现了PriorityOrdered、Ordered接口以及普通的BeanPostProcessor
    for (String ppName : postProcessorNames) {
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            // 此处调用了getBean()方法,因此在此处就会实例化出BeanPostProcessor
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            priorityOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        }
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // First, register the BeanPostProcessors that implement PriorityOrdered.
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    // 将实现了PriorityOrdered接口的BeanPostProcessor添加到BeanFactory的beanPostProcessors集合中
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    // 下面这部分代码与上面的代码逻辑一致,是将实现了Ordered接口以及普通的BeanPostProcessor实例化以及添加到beanPostProcessors结合中,逻辑与处理PriorityOrdered的后置处理器一样
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
    for (String ppName : orderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        orderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);

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

    // Finally, re-register all internal BeanPostProcessors.
    sortPostProcessors(internalPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, internalPostProcessors);

    // Re-register post-processor for detecting inner beans as ApplicationListeners,
    // moving it to the end of the processor chain (for picking up proxies etc).
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));

    // 最后将ApplicationListenerDetector这个后置处理器一样重新放入到beanPostProcessor中,这样做的目的是为了将其放入到后置处理器的最末端
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

从上面的源码中可以发现,BeanPostProcessor存在优先级,实现了PriorityOrdered接口的优先级最高,其次是Ordered接口,最后是普通的BeanPostProcessor。优先级最高的,会最先放入到beanPostProcessors这个集合的最前面,这样在执行时,会最先执行优先级最高的后置处理器(因为List集合是有序的)。

这样在实际应用中,如果我们碰到需要优先让某个BeanPostProcessor执行,则可以让其实现PriorityOrdered接口或者Ordered接口。

# 6.3 initMessageSource()

用来支持消息国际化,现在一般项目中不会用到国际化相关的知识。

# 6.4 initApplicationEventMulticaster()

该方法初始化了一个事件广播器,如果容器中存在了beanNameapplicationEventMulticaster的广播器,则使用该广播器;如果没有,则初始化一个SimpleApplicationEventMulticaster。该事件广播器是用来做应用事件分发的,这个类会持有所有的事件监听器(ApplicationListener),当有ApplicationEvent事件发布时,该事件监听器能根据事件类型,检索到对该事件感兴趣的ApplicationListener

initApplicationEventMulticaster()方法的源码如下(省略了部分日志信息):

 protected void initApplicationEventMulticaster() {
     ConfigurableListableBeanFactory beanFactory = getBeanFactory();
     // 判断spring容器中是否已经存在beanName = applicationEventMulticaster的事件广播器
     // 例如:如果开发人员自己注册了一个
     // 如果存在,则使用已经存在的;否则使用spring默认的:SimpleApplicationEventMulticaster
     if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
         this.applicationEventMulticaster =
                 beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
     }
    else {
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
    }
}
# 6.5 onRefresh()

执行其他的初始化操作,例如和SpringMVC整合时,需要初始化一些其他的bean,但是对于纯Spring工程来说,onRefresh()方法是一个空方法。

# 6.6 registerListeners()

这一步会将自定义的listenerbean名称放入到事件广播器中,同时还会将早期的ApplicationEvent发布(对于单独的Spring工程来说,在此时不会有任何ApplicationEvent发布,但是和SpringMVC整合时,SpringMVC会执行onRefresh()方法,在这里会发布事件)。方法源码如下:

protected void registerListeners() {
    // Register statically specified listeners first.
    for (ApplicationListener<?> listener : getApplicationListeners()) {
  getApplicationEventMulticaster().addApplicationListener(listener);
    }

    // 从BeanFactory中找到所有的ApplicationListener,但是不会进行初始化,因为需要在后面bean实例化的过程中,让所有的BeanPostProcessor去改造它们
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
        // 将事件监听器的beanName放入到事件广播器中
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }

    // 发布早期的事件(纯的spring工程,在此时一个事件都没有)
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (earlyEventsToProcess != null) {
        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}
# 6.7 finishBeanFactoryInitialization()

该方法十分重要,它完成了所有非懒加载的单例Bean的实例化和初始化,属性的填充以及解决了循环依赖等问题。由于微信平台对文章字数有限制,因此关于Bean的创建过程移到了另外一篇文章中,点击后面链接查看。(通过源码看Bean的创建过程 (opens new window))

《通过源码看Bean的创建过程》这边文章中通过源码分析了所有后置处理器的作用,Bean的生命周期,以及后置处理的应用场景。

# 6.8 finishRefresh()

执行到这一步,Spring容器的启动基本结束了,此时Bean已经被实例化完成,且完成了自动装配。执行finishRefresh()方法,是为了在容器refresh()结束时,做一些其他的操作,例如:发布ContextRefreshedEvent事件,这样当我们想在容器refresh完成后执行一些特殊的逻辑,就可以通过监听ContextRefreshedEvent事件来实现。Spring内置了四个和应用上下文(ApplicationContextEvent)有关的事件:ContextRefreshedEventContextStartedEventContextStopedEventContextClosedEvent

protected void finishRefresh() {
    clearResourceCaches();
    initLifecycleProcessor();
    getLifecycleProcessor().onRefresh();
    // 发布ContextRefreshedEvent
    publishEvent(new ContextRefreshedEvent(this));
    LiveBeansView.registerApplicationContext(this˛);
}
# 6.9 resetCommonCaches()

最后在refresh()方法的finally语句块中,执行了resetCommonCaches()方法。因为在前面创建bean时,对单例bean的元数据信息进行了缓存,而单例bean在容器启动后,不会再进行创建了,因此这些缓存的信息已经没有任何用处了,在这里进行清空,释放部分内存。

protected void resetCommonCaches() {
    ReflectionUtils.clearCache();
    AnnotationUtils.clearCache();
    ResolvableType.clearCache();
    CachedIntrospectionResults.clearClassLoader(getClassLoader());
}

# 7. 总结

  • 本文介绍了Spring的启动流程,通过AnnotationConfigApplicationContext的有参构造方法入手,重点分析了this()方法和refresh()方法。在this()中初始化了一个BeanFactory,即DefaultListableBeanFactory;然后向容器中添加了7个内置的bean,其中就包括ConfigurationClassPostProcessor
  • refresh()方法中,又重点分析了invokeBeanFactoryPostProcessor()方法和finishBeanFactoryInitialization()方法。
  • invokeBeanFactoryPostProcessor()方法中,通过ConfigurationClassPostProcessor类扫描出了所有交给Spring管理的类,并将class文件解析成对应的BeanDefinition
  • finishBeanFactoryInitialization()方法中,完成了非懒加载的单例Bean的实例化和初始化操作,主要流程为getBean() ——>doGetBean()——>createBean()——>doCreateBean()。在bean的创建过程中,一共出现了8BeanPostProcessor的执行,在这些后置处理器的执行过程中,完成了AOP的实现、bean的自动装配、属性赋值等操作。
  • 最后通过一张流程图,总结了Spring中单例Bean的生命周期。

# 参考

https://mp.weixin.qq.com/s/q6zs7xRjpcB4YxLw6w477w (opens new window)

Last Updated: 3/28/2022, 9:29:49 PM