Spring 之 SpringBean的生命周期

参考文章:Spring 的生命周期

Spring作为当前Java最流行、最强大的轻量级框架,受到了程序员的热烈欢迎。准确的了解Spring Bean的生命周期是非常必要的。我们通常使用ApplicationContext作为Spring容器。这里,我们讲的也是 ApplicationContext中Bean的生命周期。

生命周期流程图:

Spring Bean的完整生命周期从创建Spring容器开始,到最终销毁Spring容器,中间包含一些列的关键点:

Spring 之 SpringBean的生命周期

Spring 之 SpringBean的生命周期

若容器注册了以上各种接口,程序那么将会按照以上的流程进行。下面将仔细讲解各接口作用。

二、各种接口方法分类

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>

 

运行结果:

Spring 之 SpringBean的生命周期