java面试-spring中bean的生命周期(详解)_依嘫_吃代码的博客-爱代码爱编程
系列文章目录
文章目录
一、Bean的主要四个阶段
Spring bean的生命周期只有四个主要阶段,其他都是在这四个主要阶段前后的扩展点,这四个阶段是:
1.实例化 Instantiation
2.属性赋值 Populate
3.初始化 Initialization
4.销毁 Destruction
其中实例化和属性赋值分别对应构造方法和setter方法的注入,初始化和销毁是用户能自定义扩展的两个阶段。
二、前置处理器和后置处理器
前置处理器是在实例化前后进行干预
后置处理器是在初始化前后进行干预
这里面以后置处理器为例:
-
作用:在调用初始化方法前后对bean进行额外的处理。
-
实现:
- 实现BeanPostProcessor接口
- 重写方法
- postProcessBeforeInitialization(Object, String):在bean的初始化之前执行
- postProcessAfterInitialization(Object, String):在bean的初始化之后执行
- 在容器中装配后置处理器
-
注意:装配后置处理器会为当前容器中每个bean均装配,不能为局部bean装配后置处理器
添加后置处理器后bean的生命周期
① 通过构造器或工厂方法创建bean实例
② 为bean的属性设置值和对其他bean的引用
postProcessBeforeInitialization(Object, String):在bean的初始化之前执行
③ 调用bean的初始化方法
postProcessAfterInitialization(Object, String):在bean的初始化之后执行
④ bean可以使用了
⑤ 当容器关闭时,调用bean的销毁方法
-
1、实例化----实例化的过程是一个创建Bean的过程,即调用Bean的构造函数,单例的Bean放入单例池中。
-
2、初始化----初始化的过程是一个赋值的过程,即调用Bean的setter,设置Bean的属性。
三、扩展点——多个bean的接口
1.多次干预
两个最重要的接口:
InstantiationAwareBeanPostProcessor
BeanPostProcessor
实现这两个接口的bean,会自动切入到相应的生命周期中,其中InstantiationAwareBeanPostProcessor是作用于实例化阶段的前后,BeanPostProcessor是作用于初始化阶段的前后。
/*
四个主生命周期
(1)实例化之前干预 InstantiationAwareBeanPostProcessorAdapter.postProcessBeforeInstantiation()
1.实例化
(2)实例化之后干预 InstantiationAwareBeanPostProcessorAdapter.postProcessAfterInstantiation()
2.填充属性(给属性赋值)
(1)初始化之前干预 BeanPostProcessor.postProcessBeforeInitialization()
3.初始化化(比如准备资源文件)
3) 属性进行干预 ----修改属性或属性值
(2)初始化之后干预 BeanPostProcessor.postProcessAfterInitialization()
4.销毁(释放资源---对象从内存销毁)
N个接口
1、干预多次
1)BeanPostProcessor
2、干预一次
1)Aware
*/
2.只干预一次
与aware有关的接口
BeanNameAware
BeanFactoryAware
ApplicationContextAware
需要实体类实现这些接口,分别调用 Bean 的 setBeanName() 方法传入当前 Bean 的 id 值,调用 setBeanFactory() 方法传入当前工厂实例的引用,调用 setApplicationContext() 方法传入当前 ApplicationContext 实例的引用。
总结
Bean 生命周期的整个执行过程描述如下:
- 如果创建了一个类继承了InstantiationAwareBeanPostProcessorAdapter接口,并在配置文件中配置了该类的注入,即InstantiationAwareBeanPostProcessorAdapter和bean关联,则Spring将调用该接口的postProcessBeforeInstantiation()方法。
- 根据配置情况调用 Bean 构造方法或工厂方法实例化 Bean。
- 如果InstantiationAwareBeanPostProcessorAdapter和bean关联,则Spring将调用该接口的postProcessAfterInstantiation()方法。
利用依赖注入完成 Bean 中所有属性值的配置注入。 -
- 如果 Bean 实现了 BeanNameAware 接口,则 Spring 调用 Bean 的 setBeanName() 方法传入当前 Bean 的 id 值。
- 如果 Bean 实现了 BeanFactoryAware 接口,则 Spring 调用 setBeanFactory() 方法传入当前工厂实例的引用。
- 如果 Bean 实现了 ApplicationContextAware 接口,则 Spring 调用 setApplicationContext() 方法传入当前 ApplicationContext 实例的引用。
- 如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的预初始化方法 postProcessBeforeInitialzation() 对 Bean 进行加工操作,此处非常重要,Spring 的 AOP 就是利用它实现的。
- 如果 Bean 实现了 InitializingBean 接口,则 Spring 将调用 afterPropertiesSet() 方法。
- 如果在配置文件中通过 init-method 属性指定了初始化方法,则调用该初始化方法。
- 如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的初始化方法 postProcessAfterInitialization()。注意:以上工作完后才能以后就可以应用这个bean了,那这个bean是一个singleton的,所以一般这种情况下我们调用同一个id的bean会是在内容地址相同的实例,当然在spring配置文件中也可以配置非Singleton。
- 如果 Bean 实现了 DisposableBean 接口,则 Spring 会调用 destory() 方法将 Spring 中的 Bean 销毁;如果在配置文件中通过 destory-method 属性指定了 Bean 的销毁方法,则 Spring 将调用该方法对 Bean 进行销毁。