Spring源码学习1——容器启动流程
总结:
第一步、调用无参构造:
- 调用父类午餐构造,初始化BeanFactrory
- 实例化BeanDefinitionReader读取器
- 实例化一个ClassPathBeanDefinitionScanner扫包器
第二步、注册BeanDefinition到容器:
- 根据Conditional注解决定是否跳过此步
- 对通用注解做一些处理
- 封装一个BeanDefinitionHolder
- 处理scopeProxyMode,根据@Scope注解决定代理为单例【默认】还是原型【TARGET_CLASS】
- 注册BeanDefinitionHolder到registry
第三步、刷新容器:
- 3.1刷新预处理方法:,暂时空的,可以自行继承实现。用于处理属性和校验属性、添加事件等。【prepareRefresh()】
- 3.2获取Bean工厂【obtainBeanFactory】
- 刷新工厂,给他生成一个序列化id【refreshBeanFactory】
- 返回工厂【getBeanFactory】
- 3.3.BeanFactory的预处理工作。【prepareBeanFactory】
- 设置类加载器、表达解析器等,设置ApplicationContextAwarePostProcessor
- 设置需要忽略装配、需要全局可装配的
- 添加ApplicationLitensnerDetector, 添加AspectJ支持, 给工厂设置enviroment
- 3.4.初始化BeanFactory,调用后置处理postProcessBeanFactory【暂时空的】
- 3.5.执行BeanFactory初始化后置处理器。【invokeBeanFactoryPostProcessors】
- 注意两个接口:BeanFactoryPostProcessor、BeanDefinitionRegisterPostProcessor。一个执行依次针对整容器的Bean,一个针对每个Bean执行多次
- 先执行BeanDefinitionRegisterPostProcessor,后执行BeanFactoryPostProcessor,他们的执行步骤为:
- 先排序并执行实现了PriorityOrdered的后置处理器
- 排序并执行实现@Ordered接口的后置处理器
- 执行没有实现二者的后置处理器
- 3.6.注册Bean的后置处理器【registerBeanPostProcessors】,注意多种,MergedBeanDefinitionPostProcessor 特殊处理。
- 先排序并执行实现了PriorityOrdered接口的BeanPostProcessor
- 在排序并执行实现了Ordered接口的BeanPostProcessor
- 最后执行没有实现优先级和顺序接口的BeanPostProcessor
- 注册internalPostProcessors中的BeanPostProcessor,即MergedBeanDefinitionPostProcessor 。
- 添加探查后置处理器,用于检查是不是监听器,是的话添加到容器
- 3.7初始化MessageSource组件【initMessageSource】
- 3.8初始化事件派发器【initApplicationEventMulticaster】
- 3.9.刷新容器,留给子容器。【onRefresh】
- 3.10.注册所有配置的监听器【registerListeners】
- 3.11.初始化剩余的非抽象、单实例、非懒加载Bean
- 先尝试从map获取,获取不到,开始创建bean流程【重点,后面单独分析】
- 3.12.扫尾工作,如清除缓存、发布容器刷新事件等【finishRefresh】
零、编写测试代码
- bean
@Data
@AllArgsConstructor
public class Book {
private String name;
private double price;
public void init(){
System.out.println("bean初始化");
}
public void destroy(){
System.out.println("bean销毁");
}
}
- 配置类注册
@Configuration
@ComponentScan({"org.example"})
public class SpringConfig {
@Bean(initMethod = "init",destroyMethod = "destroy")
public Book book(){
return new Book("挪威的森林",100.0);
}
}
- BeanPostProcessor回调
@Component
public class myProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor初始化前置执行");
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor初始化后置执行");
return bean;
}
}
- 测试
public class App {
public static void main( String[] args ){
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(SpringConfig.class);
Book book = context.getBean(Book.class);
System.out.println(book.toString());
context.close();
}
}
在new容器哪里打上断点:
一、进入new容器
- 第一步调用无参构造
- 注册到容器中
- 刷新容器
1.无参构造:实例化BeanFac、实例化BeanDefinitionReader读取器、实例化ClassPathBeanDefinitionScanner扫包器
- 先执行父类初始化方法:实例化一个BeanFactory
- 实例化BeanDefinitionReader读取器【this.reader = new AnnotatedBeanDefinitionReader(this);】
- 添加两个BeanFactory后置处理器:【ConfigurationClassPostProcessor】、【EventListenerMethodProcessor】
- 添加两个Bean后置处理器:【AutowiredAnnotationBeanPostProcessor】、【CommonAnnotationBeanPostProcessor】
- 向容器添加普通组件:【DefaultEventListenerFactory】
- 实例化一个ClassPathBeanDefinitionScanner扫包器【this.scanner = new ClassPathBeanDefinitionScanner(this);】
1.1调用父类无参构造初始化BeanFactory:
1.2.初始化BeanDefinitionReader读取器:new AnnotatedBeanDefinitionReader
1.3实例化ClassPathBeanDefinitionScanner扫包器:new ClassPathBeanDefinitionScanner
2.注册的BeanDefinition到容器
扫描并解析配置类生成BeanDefinition,注册到容器。
- 根据@Conditional决定是否跳过
- 处理类上的注解
- 封装一个BeanDefinitionHolder
- 处理scopeProxyMode,根据@Scope注解创建单例代理【默认】/原型代理【TARGET_CLASS】。
- 将BeanDefinitionHolder注册到regisy
Befinition大致长这样:
后面还有不想截了。
3.刷新容器(重点)
3.1.刷新预处理方法:prepareRefresh();——暂时空的,可以子类重写对之做个性化处理
查看刷新预处理方法:
3.1.1.属性设置:initPropertySources();
set和日志处理不用管,查看第一个方法,作用大概是初始化一些属性设置:
居然是空的,这里实际是留给子类做一些事情的,如自己可以写一个子类,重写此方法,做一些个性化属性处理。
3.1.2.属性校验:getEnvironment().validateRequiredProperties();
因为这里没有自定义属性,自然也不会去校验,所以这里就不看了
3.1.3.事件创建:earlyApplicationEvents = new LinkedHashSet();
保存一些事件。
3.2.获取Bean工厂:this.obtainFreshBeanFactory();
发现1刷新工厂,2获取工厂
3.2.1.刷新工厂refreshBeanFactory
进入刷新工厂方法refreshBeanFactory,设置一个序列化id。
综述,此步骤作用:创建工程对象,给工厂设置一个序列化id。
3.2.2.获取bean工厂:getBeanFactory
进入进入GenericApplicationContext类
3.3.beanFactory的预准备工作:prepareBeanFactory
- 设置类加载器、表达式解析器等等
- 设置AppContextAwareBeanPostProcessor
- 设置忽略自动装配的接口
- 设置可以在任一组件注入的接口,如:容器、资源加载器、事件发布器
- 添加ApplicationLitensnerDetector
- 添加AspectJ支持
- 给工厂设置enviroment
3.4.BeanFactory后置处理:this.postProcessBeanFactory(beanFactory);——暂时空的,执行到这里bf标准初始化已完成
进入发现:
空的,可以写IOC容器的子类重写该方法,对工厂做一个后置处理。
BeanFactory标准初始化已完成
3.5.执行beanFactory的后置处理器:invokeBeanFactoryPostProcessors
**注意两个接口:**BeanFactoryPostProcessor,BeanDefinitionRegistryPostProcessor。二者用于在容器加载Bean后,实例化之前对Bean的进行修改或(修改元数据或添加逻辑),但是前者是对整个BeanFactory,仅执行一次;后者对每个Bean,每个Bean一次。
点进去第一个invoke:
- 先找到所有的BeanDefinitionRegisterPostProcessor
- 先排序并执行实现了PriorityOrdered接口的BeanDefinitionRegisterPostProcessor
- 在排序并执行实现了Ordered接口的BeanDefinitionRegisterPostProcessor
- 最后执行没有实现优先级和顺序接口的BeanDefinitionRegisterPostProcessor
- 找到所有BeanFactoryPostProcessor
- 先排序并执行实现了PriorityOrdered接口的BeanFactoryPostProcessor
- 在排序并执行实现了Ordered接口的BeanFactoryPostProcessor
- 最后执行没有实现优先级和顺序接口的BeanFactoryPostProcessor
3.6.执行Bean的后置处理器:registerBeanPostProcessors
注意有多种BeanPostProcessor,:
BeanPostProcessor:初始化前后对bean进行处理
DestructionAwareBeanPostProcessor:销毁前后对bean进行处理
InstantiationAwareBeanPostProcessor:实例化前后进行处理
SmartInstantiationAwareBeanPostProcessor:对实例化过程进行干预,预测Bean实际类型,提前暴露实例以解决循环依赖。
MergedBeanDefinitionPostProcessor :BeanDefinition合并后,bean实例化前,对合并的BeanDefinition处理。注意这个会存放到internalPostProcessors。
不同类型的执行时机是不一样的:
- 先找到所有的BeanPostProcessor
- 先排序并执行实现了PriorityOrdered接口的BeanPostProcessor
- 在排序并执行实现了Ordered接口的BeanPostProcessor
- 最后执行没有实现优先级和顺序接口的BeanPostProcessor
- 注册internalPostProcessors中的BeanPostProcessor,即MergedBeanDefinitionPostProcessor 。
- 添加探查后置处理器,用于检查是不是监听器,是的话添加到容器
点进去看新注册的后置处理器,观察其作用。
3.7.初始化MessageSource组件:this.initMessageSource();
获取BeanFactory,查看有无MesageSource组件,有则赋值,无则new一个默认的DelegatingMessageSource并注册到容器。
负责国际化,消息绑定,消息解析。
3.8.初始化事件派发器:this.initApplicationEventMulticaster();
- 获取BeanFactory工厂
- 获取自己配置的事件派发器:applicationEventMulticaster
- 如果没有配置,new一个默认的SimpleApplicationEventMulticaster,并单例地注册到BeanFactory
3.9.容器刷新方法,留给子容器:this.onRefresh();
空的,子类重写该方法,在容器刷新地时候可以自定义逻辑。
3.10.注册所有配置地监听器:this.registerListeners();
1.获取所有直接注册的事件监听器:之前步骤通过getApplicationListeners加入的,并放入事件派发器
2.获取所有以Bean方式注册的事件监听器
3.迭代,放入时间派发器
4.派发早期事件:
3.11.初始化剩余单实例:this.finishBeanFactoryInitialization(beanFactory);
- 获取所有的BD信息,依次实例化
- 如果不是FactoryBean且非抽象、单实例、非懒加载
- 调用getBean初始化,会去调用doGetBean方法。
- 调用doGetBean,尝试从缓存中获取已经创建的。
- 获取不到
- 标记Bean为已创建
- 先获取依赖的Bean,先创建依赖的Bean
- 若当前Bean是单例的,启动单例创建流程:【createBean(beanName, mbd, args)】
- 让InstationAwareBeanPostProcessor拦截返回代理对象【resolveBeforeInstantiation】
- 如果没有返回代理对象,开始创建Bean:【doCreateBean】
- 利用工厂方法/构造器等通过反射机制创建实例【createBeanInstance】
- 调用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition
- 为属性赋值,【populateBean(beanName, mbd, instanceWrapper);】
- 先达到InstantiationAwareBeanPostProcessor执行postProcessAfterInstantiation
- 再拿到InstantiationAwareBeanPostProcessors执行postProcessProperties
- 注入属性,通过setter等方法通过反射赋值
- 初始化Bean,【initializeBean】
- 执行各种Aware方法,包括BeanNameAware、BeanFactoryAware、BeanClassLoaderAware【invokeAwareMethods】
- 初始化Bean,【invokeInitMethods】
- 执行BeanPostProcessor的初始化前置方法【applyBeanPostProcessorsBeforeInitialization】
- 初始化Bean,会调用初始化回调【this.invokeInitMethods】
- 执行BeanPostProcessor的初始化后置方法【applyBeanPostProcessorsAfterInitialization】
- 注册销毁Bean的销毁回调方法【registerDisposableBeanIfNecessary】
点入refresh的11步骤:
点入:
查看getBean:
3.12:发布BeanFactory容器刷新完成事件:finishRefresh()
会在这里进行一些扫尾工作,如清理缓存,初始化生命周期处理器,发布容器刷新事件等。