spring bean的生命周期
原创基础上修改,建议参考
Spring 作为当前 Java 最流行、最强大的轻量级框架,受到了程序员的热烈欢迎。准确的了解 Spring Bean 的生命周期是非常必要的。我们通常使用 ApplicationContext 作为 Spring 容器。这里,我们讲的也是 ApplicationContext 中 Bean 的生命周期。而实际上 BeanFactory 也是差不多的,只不过处理器需要手动注册。
转载请注明地址 http://www.cnblogs.com/zrtqsk/p/3735273.html,
一、生命周期流程图:
Spring Bean 的完整生命周期从创建 Spring 容器开始,直到最终 Spring 容器销毁 Bean,这其中包含了一系列关键点。
img img若容器注册了以上各种接口,程序那么将会按照以上的流程进行。下面将仔细讲解各接口作用。
二、各种接口方法分类
Bean 的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:
1、Bean 自身的方法 : 这个包括了 Bean 本身调用的方法和通过配置文件中 <bean> 的 init-method 和 destroy-method 指定的方法
2、Bean 级生命周期接口方法 : 这个包括了 BeanNameAware、BeanFactoryAware、InitializingBean 和 DiposableBean 这些接口的方法
3、容器级生命周期接口方法 : 这个包括了 InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为 “后处理器”。
4、工厂后处理器接口方法 : 这个包括了 AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer 等等非常有用的工厂后处理器 接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。这些处理器一般处理beandifinition,因为此时bean还没有实例化.
三、演示
我们用一个简单的 Spring Bean 来演示一下 Spring Bean 的生命周期。
1、首先是一个简单的 Spring Bean,调用 Bean 自身的方法和 Bean 级生命周期接口方法,为了方便演示,它实现了 BeanNameAware、BeanFactoryAware、InitializingBean 和 DiposableBean 这 4 个接口,同时有 2 个方法,对应配置文件中@Bean的 init-method 和 destroy-method。如下:
package com.hisense.smartstation.beantest;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.io.Serializable;
/**
* @ClassName: Student
* @Description: TODO
* @Create by: gaozhen
* @Date: 2022/3/3 15:49
*/
@ConfigurationProperties(prefix = "stu")
public class Student implements Serializable, InitializingBean, DisposableBean, BeanFactoryAware, BeanNameAware {
public Student() {
System.out.println("Student.constructor");
}
@Autowired
BirthDay birthDay;
private String name;
private String sex;
private int age;
public void init(){
System.out.println("Student.init");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean.afterPropertiesSet");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("BeanFactoryAware.setBeanFactory");
}
@Override
public void setBeanName(String name) {
System.out.println("BeanNameAware.setBeanName");
}
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean.destroy");
}
public String getName() {
System.out.println("Student.getName");
return name;
}
public void setName(String name) {
System.out.println("Student.setName");
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
2、接下来是演示 BeanPostProcessor 接口的方法,如下:
package com.hisense.smartstation.beantest;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
/**
* @ClassName: StudentBeanPostProcessor
* @Description: 初始化前后
* @Create by: gaozhen
* @Date: 2022/3/2 9:24
*/
@Component
public class StudentBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof Student){
System.out.println("BeanPostProcessor.postProcessBeforeInitialization");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof Student) {
System.out.println("BeanPostProcessor.postProcessAfterInitialization");
}
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
}
如上,BeanPostProcessor 接口包括 2 个方法 postProcessAfterInitialization 和 postProcessBeforeInitialization,这两个方法的第一个参数都是要处理的 Bean 对象,第二个参数都是 Bean 的 name。返回值也都是要处理的 Bean 对象。这里要注意。
3、InstantiationAwareBeanPostProcessor 接口本质是 BeanPostProcessor 的子接口,一般我们继承 Spring 为其提供的适配器类 InstantiationAwareBeanPostProcessor Adapter 来使用它,如下:
package com.hisense.smartstation.beantest;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.stereotype.Component;
/**
* @ClassName: StudentInstantiationBeanPostProcessor
* @Description: InstantiationAwareBeanPostProcessorAdapter实现了InstantiationAwareBeanPostProcessor
* 用来进行bean实例化前,后,属性注入等工作。
* @Create by: gaozhen
* @Date: 2022/3/3 10:37
*/
@Component
public class StudentInstantiationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
/**
* bean实例化之前调用
* @param beanClass
* @param beanName
* @return
* @throws BeansException
*/
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (beanClass.equals(Student.class)) {
System.out.println("InstantiationBeanPostProcessor.BeforeInstantiation()");
}
return super.postProcessBeforeInstantiation(beanClass, beanName);
}
/**
* bean实例化以后调用
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if (bean.getClass().equals(Student.class)) {
System.out.println("InstantiationBeanPostProcessor.AfterInstantiation()");
}
return super.postProcessAfterInstantiation(bean, beanName);
}
/**
* 此处可以进行依赖注入等,@autowired,@resource等注解,都是通过调用此方法进行的依赖注入
* 相关参考:
* @autowired使用AutowiredAnnotationBeanPostProcessor#postProcessProperties()方法
* @resource使用CommonAnnotationBeanPostProcessor#postProcessProperties()方法
* CommonAnnotationBeanPostProcessor进行注入,他们都是实现了InstantiationAwareBeanPostProcessor接口
* @param pvs
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if (bean.getClass()== Student.class) {
System.out.println("InstantiationBeanPostProcessor.processProperties()");
}
return super.postProcessProperties(pvs, bean, beanName);
}
/**
* 初始化前
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean.getClass().equals(Student.class)) {
System.out.println("InstantiationBeanPostProcessor.BeforeInitialization()");
}
return super.postProcessBeforeInitialization(bean, beanName);
}
/**
* 初始化后
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean.getClass().equals(Student.class)) {
System.out.println("InstantiationBeanPostProcessor.AfterInitialization()");
}
return super.postProcessAfterInitialization(bean, beanName);
}
}
这个有 3 个方法,其中第二个方法 postProcessAfterInitialization 就是重写了 BeanPostProcessor 的方法。第三个方法 postProcessPropertyValues 用来操作属性,返回值也应该是 PropertyValues 对象。
4、注入对象BirthDay
package com.hisense.smartstation.beantest;
import org.springframework.stereotype.Component;
/**
* @ClassName: BirthDay
* @Description: TODO
* @Create by: gaozhen
* @Date: 2022/3/3 14:16
*/
@Component
public class BirthDay {
String birth = "20220303";
}
这里添加一个被注入的对象给Student,主要是为了查看BirthDay这个bean是何时被注入的,参考AutowiredAnnotationBeanPostProcessor#postProcessProperties()方法
,是在Student的bean实例化以后,通过AutowiredAnnotationBeanPostProcessor#postProcessProperties()注入的,此处可添加条件断点查看.
5、工厂后处理器接口方法BeanFactoryPostProcessor,如下:
1 package springBeanTest;
2
3 import org.springframework.beans.BeansException;
4 import org.springframework.beans.factory.config.BeanDefinition;
5 import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
6 import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
7
8 public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
9
10 public MyBeanFactoryPostProcessor() {
11 super();
12 System.out.println("这是BeanFactoryPostProcessor实现类构造器!!");
13 }
14
15 @Override
16 public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0)
17 throws BeansException {
18 System.out
19 .println("BeanFactoryPostProcessor调用postProcessBeanFactory方法");
20 BeanDefinition bd = arg0.getBeanDefinition("person");
21 bd.getPropertyValues().addPropertyValue("phone", "110");
22 }
23
24 }
5、配置文件如下 beans.xml,很简单,使用 ApplicationContext, 处理器不用手动注册:
package com.hisense.smartstation.beantest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @ClassName: StudentConfiguration
* @Description: TODO
* @Create by: gaozhen
* @Date: 2022/3/3 15:56
*/
@Configuration
public class StudentConfiguration {
@Bean(initMethod = "init",destroyMethod = "destroy")
public Student getStudent(){
return new Student();
}
}
6、yml配置:
stu:
age: 20
name: testuser
执行结果
bean factory post processor called
InstantiationBeanPostProcessor.BeforeInstantiation()
Student.constructor
InstantiationBeanPostProcessor.AfterInstantiation()
InstantiationBeanPostProcessor.processProperties()
BeanNameAware.setBeanName
BeanFactoryAware.setBeanFactory
Student.setName
BeanPostProcessor.postProcessBeforeInitialization
InstantiationBeanPostProcessor.BeforeInitialization()
InitializingBean.afterPropertiesSet
Student.init
BeanPostProcessor.postProcessAfterInitialization
InstantiationBeanPostProcessor.AfterInitialization()
image-20220303162528850
image.png
网友评论