Spring 之 SpringBean的生命周期
参考文章:Spring 的生命周期
Spring作为当前Java最流行、最强大的轻量级框架,受到了程序员的热烈欢迎。准确的了解Spring Bean的生命周期是非常必要的。我们通常使用ApplicationContext作为Spring容器。这里,我们讲的也是 ApplicationContext中Bean的生命周期。
生命周期流程图:
Spring Bean的完整生命周期从创建Spring容器开始,到最终销毁Spring容器,中间包含一些列的关键点:
若容器注册了以上各种接口,程序那么将会按照以上的流程进行。下面将仔细讲解各接口作用。
二、各种接口方法分类
Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:
1、Bean自身的方法:这个包括了Bean本身调用的方法和通过配置文件中<bean>的init-method和destroy-method指定的方法
2、Bean级生命周期接口方法:这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法
3、容器级生命周期接口方法:这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。
4、工厂后处理器接口方法:这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。
三、 实例:
我们用一个简单的Spring Bean来演示一下Spring Bean的生命周期。
1、首先是一个简单的Spring Bean,调用Bean自身的方法和Bean级生命周期接口方法,为了方便演示,它实现了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这4个接口,如下:
实体类 Bean:
package com.wc.study.spring_demo1;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
/**
* Created by wangchen on 2019/1/30.
* bean自身的方法 cuetomeInit CustomDestory
* bean 级生命周期接口的方法 实现了 BeanFactoryAware BeanNameAware InitializingBean DisposableBean 的方法
*/
public class Student implements BeanFactoryAware,BeanNameAware,InitializingBean,DisposableBean{
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
System.out.println("bean 构造器实例化");
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("注入属性 setName");
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
System.out.println("注入属性 setAge");
this.age = age;
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean的实现afterPropertiesSet 能否获取到属性:" + this.getName() + " - " + this.getAge());
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("BeanFactoryAware 的 setBeanFactory方法");
}
@Override
public void setBeanName(String s) {
System.out.println("BeanNameAware 的 setBeanName 方法 传入的参数 beanName : " + s);
}
@Override
public void destroy() throws Exception {
System.out.println("DisposiableBean 的 destory方法");
}
public void customeInit(){
System.out.println("Student : 自定义的初始化方法");
}
public void customDestroy(){
System.out.println("Student : 自定义的销毁方法");
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
2. BeanPostProcessor接口的方法
package com.wc.study.spring_demo1;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* Created by wangchen on 2019/1/30.
* 容器级生命周期接口方法 后处理器
*/
public class CustomBeanPostProcessor implements BeanPostProcessor {
public CustomBeanPostProcessor() {
System.out.println("BeanPostProcessor 实现类构造器");
}
//实例化之前
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.print("BeanPostProcessor实现类 Before Initialization ===== ");
System.out.println("两个参数:bean beanName :" + bean + "--" + beanName);
return bean;
}
//实例化之后
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.print("实现了BeanPostProcessor After Initialization ===== ");
System.out.println("两个参数:bean beanName :" + bean + "--" + beanName);
return bean;
}
}
如上,BeanPostProcessor接口包括2个方法postProcessAfterInitialization和postProcessBeforeInitialization,这两个方法的第一个参数都是要处理的Bean对象,第二个参数都是Bean的name。返回值也都是要处理的Bean对象。这里要注意。
InstantiationAwareBeanPostProcessor 接口本质是BeanPostProcessor的子接口,一般我们继承Spring为其提供的适配器类InstantiationAwareBeanPostProcessor Adapter来使用它,如下:
package com.wc.study.spring_demo1;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
/**
* Created by wangchen on 2019/1/30.
*/
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
public MyInstantiationAwareBeanPostProcessor() {
super();
System.out.println("InstantiationAwareBeanPostProcessorAdapter 实现类构造器");
}
//实例化bean之前调用
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("InstantiationAwareBeanPostProcessorAdapter before instantiation");
return super.postProcessBeforeInstantiation(beanClass, beanName);
}
//实例化bean之后调用
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
System.out.println("InstantiationAwareBeanPostProcessorAdapter after instantiation");
return super.postProcessAfterInstantiation(bean, beanName);
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
System.out.println("InstantiationAwareBeanPostProcessorAdapter properties :" + pvs.toString());
return super.postProcessProperties(pvs, bean, beanName);
}
}
工厂后处理器接口方法:
package com.wc.study.spring_demo1;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
/**
* Created by wangchen on 2019/1/30.
*/
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public MyBeanFactoryPostProcessor() {
super();
System.out.println("BeanFactoryPostProcessor实现类 构造器");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println("BeanFactoryPostProcessor实现类 的 postProcessBeanFactory");
BeanDefinition beanDefinition = configurableListableBeanFactory.getBeanDefinition("student");
MutablePropertyValues mutablePropertyValues = beanDefinition.getPropertyValues();
mutablePropertyValues.addPropertyValue("name","小白");
mutablePropertyValues.addPropertyValue("age",12);
}
}
构造方法:
package com.wc.study.spring_demo1.config;
import com.wc.study.spring_demo1.*;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Created by wangchen on 2019/1/30.
*/
@Configuration
public class StudentConfig {
// @Bean(initMethod = "customeInit",destroyMethod = "customDestroy")
// public Teacher teacher(){
// return new Teacher();
// }
@Bean
public BeanPostProcessor beanPostProcessor(){
return new CustomBeanPostProcessor();
}
@Bean
public InstantiationAwareBeanPostProcessor instantiationAwareBeanPostProcessor(){
return new MyInstantiationAwareBeanPostProcessor();
}
@Bean
public BeanFactoryPostProcessor beanFactoryPostProcessor(){
return new MyBeanFactoryPostProcessor();
}
@Bean(initMethod = "customeInit",destroyMethod = "customDestroy")
public Student student(){
return new Student("王晨",23);
}
}
测试类:
package com.wc.study.spring_demo1;
import com.wc.study.spring_demo1.config.StudentConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* Hello world!
*/
public class App {
public static void main(String[] args) {
System.out.println("开始初始化容器");
ApplicationContext context = new AnnotationConfigApplicationContext(StudentConfig.class);
System.out.println("容器初始化完毕");
Student student = (Student) context.getBean("student");
System.out.println(student.getName());
System.out.println("开始关闭容器");
((AnnotationConfigApplicationContext)context).registerShutdownHook();
}
}
注意:以上需要在maven 的pom.xml 中配置依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.3.RELEASE</version>
</dependency>
运行结果: