美文网首页程序员Java 杂谈
01-Spring的启动过程分析

01-Spring的启动过程分析

作者: AcientFish | 来源:发表于2019-03-28 10:59 被阅读0次

Spring的启动过程

本文的目的是记录自己在学习Spring容器启动过程中的一些笔记,以供后面复习,也希望可以给有需要的朋友提供一点帮助。本次分析所用的Spring版本为 5.1.4.RELEASE。
首先我们从容器创建为入口,逐渐深入容器的启动过程。

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

上面这行代码大家应该都很熟悉,通过这行代码就可以完成IOC容器的初始化,让Spring帮我们管理一切。下面我们就从AnnotationConfigApplicationContext这个类开始,一层一层解开Spring的神秘面纱。

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
        /**
        此处只是初始化了Bean Definition的reader和scanner
        this.reader = new AnnotatedBeanDefinitionReader(this);
        this.scanner = new ClassPathBeanDefinitionScanner(this);
        */
        this();
        // 此处只是将传进来的配置类(AppConfig.class注册到BeanDefinitionMap中去)
        register(annotatedClasses);
        // 重点在refresh方法里面
        refresh();
    }

在前两个方法中只是做了简单的初始化ioc容器所需的对象,此时ioc容器是空的,通过refresh方法会一次来解析beandefinition并产生对象装入容器中,下面来分析refresh方法。

   // Prepare this context for refreshing.
   // 这个方法只是记录了容器启动时间,设置容器为active状态,并无实际操作,不重要。
   prepareRefresh();
   // Tell the subclass to refresh the internal bean factory.
   // 此处只是给Bean Factory设置了一个SerializationId
   ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 
   // Prepare the bean factory for use in this context.
   // 初始化了IOC容器的一些工具,比如Class Loader、EL表达式解析器和属性解析器
   prepareBeanFactory(beanFactory);
   // Allows post-processing of the bean factory in context subclasses.
   // 空方法
   postProcessBeanFactory(beanFactory);
   // Invoke factory processors registered as beans in the context.
   // 执行所有的BeanFactoryPostProcessor
   // 在ConfigurationClassPostProcessor#processConfigBeanDefinitions()方法会对所有的配置类进行处理,通过ConfigurationClassParser对象来解析,最终通过parser.parse(candidates);来调用解析方法。
   // 其中会处理所有@Configuration注解的类,解析其配置的@Bean和@ComponentScan注解,将相关的Bean扫描并加入到BeanDefinitionMaps中,之后会使用动态代理(CGLIB)增强Configuration类,增强是直接修改Bean Definition中BeanClass属性,直接替换为代理后的class
   invokeBeanFactoryPostProcessors(beanFactory);
   // 注册了两个BeanPostProcessor,一个CommonBeanPostProcessor,另一个AutoWiredBeanPostProcessor,注意,这个后置处理器很重要,他是完成自动装配的关键!
   // Register bean processors that intercept bean creation.
   registerBeanPostProcessors(beanFactory);
   // Initialize message source for this context.
   // 像BeanFactory注册了messageSource
   initMessageSource();
   // Initialize event multicaster for this context.
   // 向BeanFactory注册了applicationEventMulticaster
   initApplicationEventMulticaster();
   // Initialize other special beans in specific context subclasses.
   // 空方法,api注释中写的是允许子类添加一些特定的逻辑在实例化单例Bean之前。 before instantiation of singletons.
   onRefresh();
   // Check for listener beans and register them.
   // 将实现了ApplicationListener的类注册到applicationEventMulticaster中
   registerListeners();
   // Instantiate all remaining (non-lazy-init) singletons.
   // 实例化Bean DefinitionMap中所有的非懒加载的单例Bean
   // 前面做大堆准备工作,最终会冻结配置,防止配置发生变化(freezeConfiguration),结束后调用preInstantiateSingletons()方法来实例化,由于实例化较为重要,下面单独分析preInstantiateSingletons方法
   finishBeanFactoryInitialization(beanFactory);
   // Last step: publish corresponding event.
   // 结束启动过程,会清空在初始化过程中创建的一些缓存,同时调用LifecycleProcessor#onRefresh方法。最后会发布ContextRefreshedEvent事件。
   finishRefresh();

以上就是Spring启动的全过程,后面我们会深入分析容器的初始化过程,容器如何解析配置类,如何根据配置类来实例化单例对象等。
由于本人水平有限,难免遇到表述不清或错误的情况,如果存在任何问题,请大家及时提醒,我会在第一时间进行修正。

相关文章

网友评论

    本文标题:01-Spring的启动过程分析

    本文链接:https://www.haomeiwen.com/subject/cwofbqtx.html