Spring的bean的生命周期

来源:互联网 发布:php chmod 777 编辑:程序博客网 时间:2024/05/17 13:08

接触Spring时间越久,越觉得其设计思想对我们开发的影响之深,最近在开发项目时,组里一个师兄的项目设计就和Spring的bean生命周期设计有很多不谋而合之处,接着对项目理解,回顾了一下Spring的bean的生命周期。

本文基于ApplicationContext中的bean的生命周期为例。

生命周期流程图

Spring bean的生命周期从创建Spring容器开始到Spring的容器销毁bean。最核心关键的流程图如下:

这里写图片描述

从上图可以看出,最核心的分为三步:

  1. bean的实例化
  2. 给bean populate填充属性
  3. bean的初始化

各类接口作用域维度的分类

1. 粒度在bean自身的方法:

配置文件中<bean>的init-method和destroy-method指定的方法

2. 粒度在bean级生命周期的方法
BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法

3. 容器级生命周期接口方法
InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。

测试demo

下面定义了三个bean:

MyBeanFactoryPostProcessor实现了BeanFactoryPostProcessor,这个类在bean开始实例化之前被调用,所以可以修改bean的属性,修改每个bean里面的properties。可以理解成前置处理器

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor{    public MyBeanFactoryPostProcessor() {        System.out.println("MyBeanFactoryPostProcessor 构造器实例化");    }    @Override    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {        System.out.println("MyBeanFactoryPostProcessor#postProcessBeanFactory()");        System.out.println("count bean = "+beanFactory.getBeanDefinitionCount());        System.out.println("beanDefinitionName number is "+ beanFactory.getBeanDefinitionNames().length);        for(String beanDefinitionName : beanFactory.getBeanDefinitionNames()){            System.out.println("   "+ beanDefinitionName);        }        System.out.println("singletonNames number is "+ beanFactory.getSingletonNames().length);        for(String singletonName : beanFactory.getSingletonNames()){            System.out.println("   "+ singletonName);        }        BeanDefinition bd = beanFactory.getBeanDefinition("louyuting-user");        bd.getPropertyValues().addPropertyValue("id", "110");    }}

MyBeanPostProcessor实现了BeanPostProcessor接口,用于bean初始化前后调用、

public class MyBeanPostProcessor implements BeanPostProcessor {    public MyBeanPostProcessor() {        System.out.println("MyBeanPostProcessor 构造器实例化");    }    // 初始化之前    @Override    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {        System.out.println("bean初始化之前调用:BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!");        return bean;    }    // 初始化之后调用    @Override    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {        System.out.println("bean初始化之后调用:BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!");        return bean;    }}

MyInstantiationAwareBeanPostProcessor实现了InstantiationAwareBeanPostProcessorAdapter接口,用于bean实例化前后调用处理。

public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {    public MyInstantiationAwareBeanPostProcessor() {        System.out.println("MyInstantiationAwareBeanPostProcessor构造器");    }    // 实例化Bean之前调用    @Override    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {        System.out.println("bean实例化之前调用,InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation");        return null;    }    // 实例化Bean之后调用    @Override    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {        System.out.println("bean实例化之后前调用,InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation");        return false;    }    // 接口方法、设置某个属性时调用    @Override    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean,                                                    String beanName) throws BeansException {        System.out.println("接口方法、设置某个属性时调用,InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法 ");        return pvs;    }}

User 实现了BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean四个接口。作用于bean填充属性之后执行。

public class User implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean {    private String id;    private String name;    private BeanFactory beanFactory;    private String beanName;    public User() {        System.out.println("User 构造器实例化");    }    public String getId() {        return id;    }    public void setId(String id) {        System.out.println("注入属性 id");        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        System.out.println("注入属性 name");        this.name = name;    }    // BeanFactoryAware    @Override    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {        System.out.println("【BeanFactoryAware接口】 接口调用 BeanFactoryAware.setBeanFactory(BeanFactory beanFactory)");        this.beanFactory = beanFactory;    }    // BeanNameAware    @Override    public void setBeanName(String name) {        System.out.println("【BeanNameAware接口】 接口调用 BeanNameAware.setBeanName(String name)");        this.beanName = name;    }    public void myInit() {        System.out.println("【init-method】调用<bean>的init-method属性指定的初始化方法");    }    public void myDestory() {        System.out.println("【destroy-method】调用<bean>的destroy-method 属性指定的初始化方法");    }    @Override    public void destroy() throws Exception {        System.out.println("【DiposibleBean接口】调用DiposibleBean.destory()");    }    @Override    public void afterPropertiesSet() throws Exception {        System.out.println("【InitializingBean接口】调用InitializingBean.afterPropertiesSet()");    }}

Spring的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" default-autowire="byName">    <bean id="louyuting-user" class="com.example.demo.test.ioc.User" init-method="myInit" destroy-method="myDestory">        <property name="id" value="1234"/>        <property name="name" value="louyuting"/>    </bean>    <bean id="beanPostProcessor" class="com.example.demo.test.ioc.MyBeanPostProcessor">    </bean>    <bean id="instantiationAwareBeanPostProcessor" class="com.example.demo.test.ioc.MyInstantiationAwareBeanPostProcessor">    </bean>    <bean id="beanFactoryPostProcessor" class="com.example.demo.test.ioc.MyBeanFactoryPostProcessor">    </bean></beans>

测试运行主函数:

public class BeanLifeCycleTest {    public static void main(String[] args) {        ConfigurableApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:bean.xml");        User user = applicationContext.getBean("louyuting-user", User.class);        System.out.println(user);        applicationContext.registerShutdownHook();    }}

测试运行结果

MyBeanFactoryPostProcessor 构造器实例化MyBeanFactoryPostProcessor#postProcessBeanFactory()count bean = 4beanDefinitionName number is 4   louyuting-user   beanPostProcessor   instantiationAwareBeanPostProcessor   beanFactoryPostProcessorsingletonNames number is 4   environment   systemProperties   systemEnvironment   beanFactoryPostProcessorMyBeanPostProcessor 构造器实例化MyInstantiationAwareBeanPostProcessor构造器bean实例化之前调用,InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiationUser 构造器实例化bean实例化之后前调用,InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation【BeanNameAware接口】 接口调用 BeanNameAware.setBeanName(String name)【BeanFactoryAware接口】 接口调用 BeanFactoryAware.setBeanFactory(BeanFactory beanFactory)bean初始化之前调用:BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!【InitializingBean接口】调用InitializingBean.afterPropertiesSet()【init-method】调用<bean>的init-method属性指定的初始化方法bean初始化之后调用:BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!com.example.demo.test.ioc.User@57e1b0c【DiposibleBean接口】调用DiposibleBean.destory()【destroy-method】调用<bean>的destroy-method 属性指定的初始化方法

完美验证了结果。

原创粉丝点击