Spring源码系列之容器启动流程

1. Demo创建2. 启动3. 入口4. 基础概念5. AnnotationConfigApplicationContext的构造方法5.1 this()调用5.2 register(annotatedClasses)5.3 执行refresh()方法6. refresh()方法6.1 invokeBeanFactoryPostProcessors()6.2 registerBeanPostProcessors()6.3 initMessageSource()6.4 initApplicationEventMulticaster()6.5 onRefresh()6.6 registerListeners()6.7 finishBeanFactoryInitialization()6.8 finishRefresh()6.9 resetCommonCaches()7. 总结8. 计划10. 推荐性能监控工具


1. Demo创建

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

  • 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,然后放入到BeanFactoryBeanDefinitionMap中。

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

     

 

  • 在执行过程中先执行所有的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的创建过程)

《通过源码看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的生命周期。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我尽力解释 Spring 容器启动流程源码。 1. 加载配置文件 Spring 容器启动时,首先读取配置文件,通常是 `applicationContext.xml`。配置文件中定义了需要被 Spring 管理的 bean,以及它们的依赖关系等信息。 2. 创建 BeanDefinition Spring 容器解析配置文件,创建对应的 BeanDefinition 对象。BeanDefinition 定义了 bean 的基本信息,如 bean 的类名、scope、依赖关系等等。 3. 注册 BeanDefinition 接下来,Spring 容器将创建的 BeanDefinition 注册到 BeanDefinitionRegistry 中。BeanDefinitionRegistry 是一个接口,它定义了注册、查询、删除 BeanDefinition 的方法。 4. 实例化 Bean 接下来,Spring 容器将开始实例化 bean。Spring 容器使用反射创建 bean 的实例,然后根据配置文件中的信息对 bean 进行初始化。 5. 填充属性值 在 bean 实例化之后,Spring 容器开始填充属性值。Spring 容器根据配置文件中的信息,自动为 bean 填充属性值。这些属性可以是基本类型、引用类型、集合类型等等。 6. 调用 BeanPostProcessor 在填充完属性值之后,Spring 容器调用 BeanPostProcessor 的方法。BeanPostProcessor 是一个接口,它定义了在 bean 实例化和初始化过程中的回调方法。通过实现 BeanPostProcessor,我们可以在 bean 实例化和初始化的过程中做一些自定义的操作。 7. 初始化 Bean 在填充完属性值和调用 BeanPostProcessor 之后,Spring 容器调用 bean 的初始化方法。初始化方法可以是 init-method 指定的方法,也可以是实现了 InitializingBean 接口的 afterPropertiesSet() 方法。 8. 注册销毁方法 当 bean 的生命周期结束时,Spring 容器调用它的销毁方法。销毁方法可以是 destroy-method 指定的方法,也可以是实现了 DisposableBean 接口的 destroy() 方法。 以上就是 Spring 容器启动流程的大概过程。其中,BeanDefinition、BeanPostProcessor、InitializingBean、DisposableBean 等接口和类都是 Spring 框架中提供的,它们为我们提供了更加灵活的配置和扩展方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值