清楚了解spring,可以清楚的了解项目在跑起来的时候,以下是我对spring生命周期各个阶段做了啥,并且我们可以对当前的阶段做啥事,在项目上我们可以在利用这个阶段做哪些事
Bean生命周期顺序如下
(1) 根据配置情况调用Bean构造方法或工厂方法实例化Bean。
1、这里就是获取初始化bean的相关信息,在对于BeanFactory容器,当向容器请求一个尚未初始化的bean或者初始bean的时候需要注入另外一个还没有初始化的依赖时,spring会调用createBean进行实例化。
2、对于ApplicationContext容器,其实也就是一个ConcurrentHashMap,在启动的时候,spring会扫描需要注入的所有的类,容器通过获取BeanDefinition对象中的信息进行实例化。
3、这里只是对于需要注入类实例化,并没有进行依赖注入。
4、在这里会记载。
eg: BeanWrapper承载了bean实例的包装、类型转换、属性的设置已经访问等重要作用。
(2) 设置属性值
实例在第一步被封装在BeanWrapper对象中,并且此时对象处于原生状态(没有依赖注入),在createBeanInstance里面会根据BeanDefinition中的信息进行依赖注入,并且通过BeanWrapper
提供的设置属性的接口完成依赖注入。
(3) 执行Aware
1、spring会检测当前注入的对象是否实现了Aware接口及其相关的实现类。
2、常见的有BeanNameAware、ApplicationAware等等接口,BeanNameAware可以获取当前bean在当前的name,有component设置value就是value
,默认是抬头小写。平时用的最多的是ApplicationContextAware。
(4) BeanFactoryAware接口
1、setBeanFactory:获取BeanFactory;
2、对于BeanFactory:是一个中央注册中心应用组件,并且集中配置应用程序组件
(5) ApplicationContextAware接口
eg: ApplicationContext是ListableBeanFactory -> BeanFactory,ApplicationContext是继承BeanFactory,
多了几部分功能功能,例如containsBeanDefinition,getBeanDefinitionCount,getBeanDefinitionNames,getBeanNamesForType,getBeansOfType等等方法功能
(6)BeanPostProcessor前置处理。
BeanPostProcessor是Spring IOC容器给我们提供的一个扩展接口,目的就是为了提供给相关的bean再加工的一个机会,一些Spring AOP的底层处理也是通过实现BeanPostProcessor来执行代理包装逻辑的。
(7,8)InitializingBean初始化和init-method
InitializingBean 接口只有一个函数:afterPropertiesSet()
这一阶段,也可以使用在bean构造完之前增加自定义逻辑(注意是之前),和BeanPostProcessor不同点在于,这里没有bean对象,只能添加额外的逻辑,在使用的时候,实现Initializing,
或者可以做一些配置使用init-method。(实现Initializing和配置init-method都差不多,但是前者就将Bean的代码与spring耦合在一起了,后者可以通过配置,不会对业务代码造成侵入),后者配置有两种办法,一种是通过xml,另一种是通过配置文件,springboot推荐后者
1、<bean id="xmlPerson" class="com.best.entity.Person" init-method="init" destroy-method="destroy">
2、
@Bean(initMethod="init")
public TestInitialization testInitialization() {
return new TestInitialization();
}
(9)BeanPostProcessor后置处理
postProcessAfterInitialzation( Object bean, String beanName ) 当前正在初始化的bean对象会被传递进来,我们就可以对这个bean作任何处理。
这个函数会在InitialzationBean完成后执行,因此称为后置处理,在这里bean就可以使用了
在实际中,例如有两个实现类,要做判断使用,如果开发时使用A,上线时使用B,这时候就可以使用这个修改注入的时候是哪个实现类,相关范例:https://zhuanlan.zhihu.com/p/29750396
(10)区分单例bean还是多例bean
通过@Scope判断是单例bean还是多例,singleton就是设置的单例,prototype就是设置的多例,是单例spring就将bean放入到单例池中,是多例就交给bean的调用者,一般在程序启动的时候,单例bean会被spring
通过bean的生命周期给缓存到单例池,而多例bean就处于一种原生状态,当调用的时候就会去走接下来的spring生命周期
(11)销毁(DisposableBean和destory-method)
这个和第7 8 步一样原因也一样,使用方法也一样,目的就是销毁bean;