什么是Spring Bean的生命周期
Spring Bean的生命周期是从 Bean 实例化之后,即通过反射创建出对象之后,到Bean成为一个完整对象,最终存储到单例池中,这个过程被称为Spring Bean的生命周期。Spring Bean的生命周期大体上分为四个阶段
实例化 => 初始化 => 操作使用 => 销毁
Bean生命周期详细
1. Bean的实例化
1.1 方式:
1,使用类构造器实例化(无参构造函数)
直接通过Spring工厂返回类的实例对象
2,使用静态工厂方法实例化(简单工厂模式)
Spring工厂调用自定义工厂的静态方法返回类的实例对象。
3,使用实例工厂方法实例化(工厂方法模式)
Spring工厂调用工厂的普通方法(非静态方法)返回类的实例对象。
1.2 基本流程:
1.加载注解和xml配置文件,解析获取配置中的每个的信息,封装成一个个的BeanDefinition对象
2.将BeanDefinition存储在一个名为beanDefinitionMap的Map中;
3.ApplicationContext底层遍历beanDefinitionMap,创建Bean实例对象,成一个半成品bean
1.3 Bean工厂后处理器
BeanFactoryPostProcessor:
BeanFactoryPostProcessor是一个接口规范,实现了该接口的类只要交由Spring容器管理的话,那么Spring就会回调该接口的方法,用于对BeanDefinition注册和修改的功能。
eg:
public class user {
public user() {
System.out.println("创建了user");
}
}
2.创建两个类分别实现BeanFactoryPostProcessor接口和BeanDefinitionRegistryPostProcessor接口
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println("进入了postProcessBeanFactory方法");
}
}
public class MyBeanFactoryPostProcessor2 implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
System.out.println("进入了postProcessBeanDefinitionRegistry方法");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
}
3.注入
<bean id="mbfpp" class="com.ape.factory.MyBeanFactoryPostProcessor"></bean>
<bean id="mbfpp2" class="com.ape.factory.MyBeanFactoryPostProcessor2"></bean>
<bean id="user" class="com.ape.bean.user"></bean>
4.测试
public class test {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applactionContext.xml");
System.out.println(context.getBean("user"));
}
}
5.结果
2. Bean的初始化和销毁
2.1 属性填充
BeanDefinition 中有对当前Bean实体的注入信息通过属性propertyValues进行了存储,例如
Spring在进行属性注入时,会分为如下几种情况:
- 注入普通属性,String、int或存储基本类型的集合时,直接通过set方法的反射设置进去;
- 注入单向对象引用属性时,从容器中getBean获取后通过set方法反射设置进去,如果容器中没有,则先创建被注入对象Bean实例(完成整个生命周期)后,在进行注入操作;
- 注入双向对象引用属性时,就比较复杂了,涉及了循环引用(循环依赖)Spring如何解决循环依赖
2.2 Aware接口
Aware接口是一种框架辅助属性注入的一种思想,其他框架中也可以看到类似的接口。框架具备高度封装性,我们接触到的一般都是业务代码,一个底层功能API不能轻易的获取到,但是这不意味着永远用不到这些对象,如果用到了, 就可以使用框架提供的类似Aware的接口,让框架给我们注入该对象
2.3 Bean后处理器
BeanPostProcessor
被实例化后,到最终缓存到名为singletonObjects单例池之前,中间会经过Bean的初始化过程,例如:属性的填充、初始方法init的执行等,其中有一个对外进行扩展的点BeanPostProcessor,我们称为Bean后处理。跟上面的 Bean工厂后处理器相似,它也是一个接口,实现了该接口并被容器管理的BeanPostProcessor,会在流程节点上被Spring自动调用。
2.4 销毁
接口销毁
当 Bean 不再需要时,会经过清理阶段,如果Bean 实现了 DisposableBean这个接口,会调用其实现的 destroy()方法执行销毁;
属性销毁
如果这个 Bean 的 spring 配置中配置了 destroy-method 属性,会自动调用其配置的自定义销毁方法。
eg:
1. 定义实体类, 实现各种aware接口和DisposableBean, InitializingBean (接口的初始化和销毁)
public class user implements BeanNameAware, ApplicationContextAware, BeanFactoryAware, DisposableBean, InitializingBean {
private String sname;
public void setSname(String sname) {
this.sname = sname;
System.out.println("属性注入");
}
public user() {
System.out.println("创建user");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("BeanNameAware==="+beanFactory);
}
@Override
public void setBeanName(String s) {
System.out.println("ApplicationContextAware==="+s);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("BeanFactoryAware==="+applicationContext);
}
@Override
public void destroy() throws Exception {
System.out.println("接口销毁");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("接口初始化");
}
public void dodistory(){
System.out.println("属性销毁");
}
public void doinit(){
System.out.println("属性初始化");
}
}
2.定义类实现BeanPostProcessor
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("bean后处理器的前置方法");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("bean后处理器的后置方法");
return bean;
}
}
3. 注入
<bean id="user" class="com.ape.bean.user" init-method="doinit" destroy-method="dodistory">
<property name="sname" value="Mr.li"></property>
</bean>
<bean id="MBPP" class="com.ape.factory.MyBeanPostProcessor"></bean>
4. 测试
public class test {
public static void main(String[] args) {
ClassPathXmlApplicationContext con = new ClassPathXmlApplicationContext("applicationContext.xml");
con.getBean("user");
con.close();
}
}
5. 结果
总结:
1.实例化
1) 构造器或工厂实例化
2) 执行Bean工厂后处理器的回调方法
2.初始化
1)属性填充
2)实现各种Aware接口
3)执行BeanPostProcessor的before()方法
4)执行InitializingBean接口的初始化方法
5)执行自定义初始化方法init-method
6)执行BeanPostProcessor的after()方法
3.操作使用
4.销毁
1)接口销毁
2)属性销毁