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