您的位置:首页 > 编程语言 > Java开发

Spring的bean的生命周期

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

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

生命周期流程图

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



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

bean的实例化

给bean populate填充属性

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 = 4
beanDefinitionName number is 4
louyuting-user
beanPostProcessor
instantiationAwareBeanPostProcessor
beanFactoryPostProcessor
singletonNames number is 4
environment
systemProperties
systemEnvironment
beanFactoryPostProcessor
MyBeanPostProcessor 构造器实例化
MyInstantiationAwareBeanPostProcessor构造器
bean实例化之前调用,InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
User 构造器实例化
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 属性指定的初始化方法


完美验证了结果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring bean