Spring 之bean的生命周期
今天我们来聊一下Spring Bean的生命周期,这是一个非常重要的问题,Spring Bean的生命周期也是比较复杂的。
IOC
IOC,控制反转概念需要提前了解一下,简单说就是把new对象的权利交给容器,所有的对象都由容器控制,称为控制反转
然后再通过依赖注入把它依赖的类注入给它。
Bean的生命周期
首先我们先来了解一下bean的作用域有哪些?
-
singleton: 在Spring IOC仅存在一个Bean实例,是Spring默认的bean作用域
-
prototype: 每次请求都会创建一个新的bean实例,即允许IOC中存在多个bean实例
-
request: 每次HTTP请求都会产生一个bean,该bean仅在HTTP request内有效
-
session:每一次HTTP请求都会产生一个新的bean,该bean在这个Session中共享
-
application:限定Bean的作用域为ServletContext的生命周期,该作用域仅适用于web的Spring WebApplicationContext环境
-
websocket: 限定Bean的作用域为WebSocket,该作用域仅适用于web的Spring WebApplicationContext环境
在Spring 中Bean的生命周期大致可以概况为:
实例化 -> 属性赋值 -> 初始化 -> 销毁
在Spring的Bean的生命周期种提供了很多的扩展点,常见的扩展接口有 InitializingBean, BeanNameAware, DisposableBean, ApplicationContextAware,InstantiationAwareBeanPostProcessor,BeanPostProcessor
其中的生命周期可以简单写为以下四步
-
实例化:首先,实例化一个Bean对象
-
属性赋值:为Bean对象设置属性和依赖
-
初始化:初始化,在完成后就可以被使用了
-
销毁:可以i通过第4步两种方法来添加配置
其中Bean的大致流程如图所示,展示了初始后的前置和后置过程,在实例化过程中也区分前置和后置过程,而初始化的前置和后置过程中主要是通过重写BeanPostProcessor中的postProcessBeforeInitialization和postProcessAfterInitialization实现的,销毁和初始也支持用户自定义方法。
下面我们继续来看在实例化和初始化时可以扩展的前置方法和后置方法。
运行结果
实例演示
实体类
public class User implements InitializingBean, BeanNameAware, DisposableBean, ApplicationContextAware {
private String name;
public User() {
System.out.println("1.2 User的无参构造, 实例化");
}
/**
* 初始化方法
*/
public void initMethod() {
System.out.println("3.3. bean对象的初始化,调用指定的初始化方法");
}
/**
* 销毁方法
*/
public void destroyMethod() {
System.out.println("4.2 bean对象的销毁,调用指定的销毁方法");
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("2.1 设置User.name属性 设置属性");
this.name = name;
}
@Override
public void setBeanName(String name) {
System.out.println("2.2调用BeanNameAware.setBeanName()方法");
}
@Override
public void destroy() throws Exception {
System.out.println("4.1调用 DisposableBean.destroy() 方法");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("3.2调用 InitializingBean.afterPropertiesSet() 方法");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
User user = (User)applicationContext.getBean("user");
System.out.println(user);
System.out.println("调用ApplicationContextAware.setApplicationContext()");
}
}
实例化前后置代码
public class MyBeanInstant implements InstantiationAwareBeanPostProcessor {
/**
* Spring 扩展点一、在bean实例化前和实例化后
*/
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("1.1bean的前置处理器实例前 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation");
System.out.println(beanName + ": :" + beanClass);
return InstantiationAwareBeanPostProcessor.super.postProcessBeforeInstantiation(beanClass, beanName);
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
System.out.println("1.3bean的前置处理器实例后 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation");
System.out.println(beanName + ": :" + bean);
return InstantiationAwareBeanPostProcessor.super.postProcessAfterInstantiation(bean, beanName);
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if ("user".equals(beanName)) {
System.out.println("1.4调用InstantiationAwareBeanPostProcessor.postProcessProperties()方法");
}
return InstantiationAwareBeanPostProcessor.super.postProcessProperties(pvs, bean, beanName);
}
}
初始化的前后置代码
public class MyBeanPost implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("3.1 bean的后置处理器初始化前 BeanPostProcessor.postProcessBeforeInitialization");
System.out.println(beanName + ": :" + bean);
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("3.4 bean的后置处理器初始化后 BeanPostProcessor.postProcessAfterInitialization");
System.out.println(beanName + ": :" + bean);
System.out.println();
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
}
application.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="myBeanPost" class="com.zly.ioc.life.MyBeanPost"/>
<bean id="myBeanInstant" class="com.zly.ioc.life.MyBeanInstant"/>
<bean id="user" class="com.zly.ioc.life.User" scope="singleton" init-method="initMethod" destroy-method="destroyMethod">
<property name="name" value="dy"/>
</bean>
</beans>
总结
本文主要是介绍了Bean的生命周期,简单介绍生命周期中的各种状态概念,以及各个阶段所执行的方法和操作。