spring的Bean的生命周期大体步骤
- 实例化容器
- 扫描类文件
- 解析某个类
- 实例化BeanDefinition,可以配置Lazy,Scope,dependOn,Class,beanName等
- 方式BeanDefinitionMap
- 调用实现了BeanFactoryPostProcesser方法。下面两个执行步骤都是在容器实例化之前。
- 先执行BeanDefinitionRegistryPostProcessor实现的postProcessBeanDefinitionRegistry方法,该方法可以获取到BeanDefinitionRegistry类,可以把自定义的BeanDefinition注册上去,后面容器实例化时会进行实例化。mybatis-spring就是通过这种方式实现自动注入。
- 然后会BeanFactoryPostProcesser实现的postProcessBeanFactory方法,可以得到ConfigurableListableBeanFactory对象,可以从这个对象中获得前面定义好的BeanDefinition,可以修改BeanDefinition的属性值。
- 验证,是否单例,是否正在创建,销毁中等
- 推断构造方法
- 反射实例化对象
- 合并hd
- 把实例保证为工厂对象,提前暴露,放入三级缓存。这步主要是为了解决循环依赖。
- 判断是否需要属性注入
- 属性注入。
- 假设实例化的是A,并且A依赖B,B依赖A。在注入B时会从各级缓存获取B的实例b,没有的话会按照上线流程创建b,b执行到属性注入这步时需要注入a,从三级缓存earlySingletonObjects中获取到提前暴露的工厂对象,工厂对象会判断是否a会否有aop,如果没有直接返回a实例,如果有则会对a进行aop代理操作,并且会执行a各种后置处理器,并返回a的代理对象(持有实际的a),然后会把a的代理对象放入二级缓存singletonFactories中,那么b注入的就是a的代理类。
- b注入a后继续执行自身的步骤
- 调用Awre接口实现。BeanNameAwre,ApplicationAwre。
- 执行BeanPostProcessor自定义实现方法
- InstantiationAwareBeanPostProcessor实现了BeanPostProcessor,新增了两个实现方法postProcessBeforeInstantiation、postProcessAfterInstantiation,分布在bean实例化之前和实例化之后调用。
- 自定义实现了BeanPostProcessor的类会调用postProcessBeforeInitialization、postProcessAfterInitialization两个方法,分别是在bean初始化前和初始化后调用。
- 上述调用先后顺序是实例化前>实例化后>初始化前>初始化后
- 执行生命周期回调方法
- @PostConstruct
- InitializingBean#afterPropertiesSet
- init-method
- 完成AOP代理
- 放入单例池,也就是一级缓存singletonObjects。这一步完成表示bean对象实例化完成。
- 销毁。调用销毁回调方法,DiposibleBean的destroy方法,destroy-method修饰方法。
为什么要用三级缓存
如果只使用二级缓存,在b注入a时,只能注入a的实例,没有办法注入代理后的a,而使用三级缓存,在三级缓存存入一个工厂对象,工厂对象中可以处理aop后返回代理后的a。
循环依赖图解,来源网络https://blog.csdn.net/chaitoudaren/article/details/105060882