Spring之Bean的生命周期

栏目: Java · 发布时间: 6年前

内容简介:该接口中的方法是最先执行的。在Bean实例化之前执行该接口中定义了两个方法,分别在Bean对象实例化及装配后在初始化的前后执行该接口是BeanPostProcessor接口的子接口,所以该接口肯定具有BeanPostProcessor接口的功能,同时又定义了三个自己的接口,这三个接口是在Bean实例化前后执行的方法。
Spring之Bean的生命周期

二、生命周期方法说明

接口 方法 说明
BeanFactoryPostProcessor postProcessBeanFactory 在Bean对象实例化之前执行, 通过beanFactory可以获取bean的定义信息, 并可以修改bean的定义信息。这点是和BeanPostProcessor最大区别
BeanPostProcessor postProcessBeforeInitialization 实例化、依赖注入完毕,在调用显示的初始化之前完成一些定制的初始化任务
postProcessAfterInitialization 实例化、依赖注入、初始化完毕时执行
InstantiationAwareBeanPostProcessor postProcessBeforeInstantiation 在方法实例化之前执行,返回结果为null正常执行,返回结果如果不为null则会跳过相关方法而进入初始化完成后的流程
postProcessAfterInstantiation 在方法实例化之后执行,返回结果true才会执行postProcessPropertyValues方法
postProcessPropertyValues 可以用来修改Bean中属性的内容
InitializingBean afterPropertiesSet 初始化的方法
DisposableBean destroy 容器销毁前的回调方法
Aware setXXX 感知对应Spring容器的内容
@PostConstruct 标注在方法头部,表示初始化的方法
@PreDestroy 标注在方法头部,表示销毁前回调的方法
init-method属性 指定初始化的方法
destory-method属性 指定销毁前的回调方法

三、演示

1.BeanFactoryPostProcessor接口

该接口中的方法是最先执行的。在Bean实例化之前执行

/**
 * 自定义BeanFactoryPostProcessor
 * 
 * @author dengp
 *
 */
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

	/**
	 * 本方法在Bean对象实例化之前执行,
	 * 通过beanFactory可以获取bean的定义信息,
	 * 并可以修改bean的定义信息。这点是和BeanPostProcessor最大区别
	 */
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		
		System.out.println("****** BeanFactoryPostProcessor 开始执行了");
		/*String[] names = beanFactory.getBeanDefinitionNames();
		for (String name : names) {
			if("user".equals(name)){
				
				BeanDefinition beanDefinition = beanFactory.getBeanDefinition(name);
				MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
				// MutablePropertyValues如果设置了相关属性,可以修改,如果没有设置则可以添加相关属性信息
				if(propertyValues.contains("name")){
					propertyValues.addPropertyValue("name", "bobo");
					System.out.println("修改了属性信息");
				}
			}
		}*/
		System.out.println("******* BeanFactoryPostProcessor 执行结束了");
	}
}
复制代码

2.BeanPostProcessor接口

该接口中定义了两个方法,分别在Bean对象实例化及装配后在初始化的前后执行

/**
 * 自定义BeanPostProcessor实现类
 * BeanPostProcessor接口的作用是:
 * 	 我们可以通过该接口中的方法在bean实例化、配置以及其他初始化方法前后添加一些我们自己的逻辑
 * @author dengp
 *
 */
public class MyBeanPostProcessor implements BeanPostProcessor{

	/**
	 * 实例化、依赖注入完毕,在调用显示的初始化之前完成一些定制的初始化任务
	 * 注意:方法返回值不能为null
	 * 如果返回null那么在后续初始化方法将报空指针异常或者通过getBean()方法获取不到bena实例对象
	 * 因为后置处理器从Spring IoC容器中取出bean实例对象没有再次放回IoC容器中
	 */
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if("user".equals(beanName)){
			System.out.println(">>后置处理器 before方法:"+bean+"\t"+beanName);
		}
		
		// 可以根据beanName不同执行不同的处理操作
		return bean;
	}

	/**
	 * 实例化、依赖注入、初始化完毕时执行 
	 * 注意:方法返回值不能为null
	 * 如果返回null那么在后续初始化方法将报空指针异常或者通过getBean()方法获取不到bena实例对象
	 * 因为后置处理器从Spring IoC容器中取出bean实例对象没有再次放回IoC容器中
	 */
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if("user".equals(beanName)){
			System.out.println("<<后置处理器after方法:"+bean+"\t"+beanName);
		}
		// 可以根据beanName不同执行不同的处理操作
		return bean;
	}
}
复制代码

3.InstantiationAwareBeanPostProcessor接口

该接口是BeanPostProcessor接口的子接口,所以该接口肯定具有BeanPostProcessor接口的功能,同时又定义了三个自己的接口,这三个接口是在Bean实例化前后执行的方法。

/**
 * 自定义处理器
 * @author dengp
 *
 */
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor{

	/**
	 * BeanPostProcessor接口中的方法
	 * 在Bean的自定义初始化方法之前执行
	 * Bean对象已经存在了
	 */
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		// TODO Auto-generated method stub
		if("user".equals(beanName)){
			System.out.println("【---InstantiationAwareBeanPostProcessor---】 postProcessBeforeInitialization");
		}
		
		return bean;
	}

	/**
	 * BeanPostProcessor接口中的方法
	 * 在Bean的自定义初始化方法执行完成之后执行
	 * Bean对象已经存在了
	 */
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if("user".equals(beanName)){
			System.out.println("【--InstantiationAwareBeanPostProcessor----】 postProcessAfterInitialization");
		}
		return bean;
	}

	/**
	 * InstantiationAwareBeanPostProcessor中自定义的方法
	 * 在方法实例化之前执行  Bean对象还没有
	 */
	@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		if("user".equals(beanName)){
			System.out.println("【--InstantiationAwareBeanPostProcessor----】postProcessBeforeInstantiation");
		}
		return null;
	}

	/**
	 * InstantiationAwareBeanPostProcessor中自定义的方法
	 * 在方法实例化之后执行  Bean对象已经创建出来了
	 */
	@Override
	public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		if("user".equals(beanName)){
			System.out.println("【--InstantiationAwareBeanPostProcessor----】postProcessAfterInstantiation");
		}
		return true;
	}

	/**
	 * InstantiationAwareBeanPostProcessor中自定义的方法
	 * 可以用来修改Bean中属性的内容
	 */
	@Override
	public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean,
			String beanName) throws BeansException {
		if("user".equals(beanName)){
			System.out.println("【--InstantiationAwareBeanPostProcessor----】postProcessPropertyValues--->");
		}
		return pvs;
	}
}
复制代码

4.BeanNameAware,BeanFactoryAware等Aware接口

Aware接口是用来让对象感知当前的IOC环境

5.InitializingBean,DisposableBean接口

这两个接口是Bean初始化及销毁回调的方法。

6.@PostConstruct和@PreDestroy注解

package com.dpb.pojo;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
/**
 * 实现InitializingBean和DisposableBean接口
 * @author dengp
 *
 */
public class User implements InitializingBean,DisposableBean,BeanNameAware,BeanFactoryAware{

	private int id;
	
	private String name;
	//感知本对象在Spring容器中的id属性
	private String beanName;
	// 感知本对象所属的BeanFactory对象
	private BeanFactory factory;
	
	public User(){
		System.out.println("构造方法被执行了...User 被实例化");
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		System.out.println("《注入属性》注入name属性"+name);
		this.name = name;
	}

	public String getBeanName() {
		return beanName;
	}

	
	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", beanName=" + beanName + "]";
	}

	/**
	 * bean对象销毁前的回调方法
	 */
	@Override
	public void destroy() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("《DisposableBean接口》destory ....");
	}

	/**
	 * 初始化的方法
	 */
	@Override
	public void afterPropertiesSet() throws Exception {
		System.out.println("初始化:《InitializingBean接口》afterPropertiesSet....");
	}

	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("【BeanFactoryAware接口】setBeanFactory");
		this.factory = beanFactory;
	}

	@Override
	public void setBeanName(String name) {
		System.out.println("【BeanNameWare接口】setBeanName");
		this.beanName = name;
	}

	public BeanFactory getFactory() {
		return factory;
	}

	/**
	 * 也是个初始化的方法
	 */
	@PostConstruct
	public void postConstruct(){
		System.out.println("初始化:【@PostConstruct】执行了...");
	}
	/**
	 * 销毁前的回调方法
	 */
	@PreDestroy
	public void preDestory(){
		System.out.println("【@preDestory】执行了...");
	} 
	/**
	 * 初始化的方法
	 * 通过bean标签中的 init-method属性指定
	 */
	public void start(){
		System.out.println("初始化:【init-method】方法执行了....");
	}
	
	/**
	 * 销毁前的回调方法
	 * 通过bean标签中的 destory-method属性指定
	 */
	public void stop(){
		System.out.println("【destory-method】方法执行了....");
	}
}
复制代码

7.init-method,destroy-method

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
	
	<context:annotation-config/>

	<bean class="com.dpb.pojo.User" id="user" init-method="start" destroy-method="stop" >
		<property name="name" value="波波烤鸭"></property>
	</bean>
	
	<!-- 注册后置处理器 -->
	<bean class="com.dpb.processor.MyBeanPostProcessor"/>
	
	
	<!-- 注册 InstantiationAwareBeanPostProcessor -->
	<bean class="com.dpb.processor.MyInstantiationAwareBeanPostProcessor"></bean>
	<!-- 注册 BeanFactoryPostProcessor对象-->
	<bean class="com.dpb.factoryprocessor.MyBeanFactoryPostProcessor"/>
</beans>
复制代码

8.测试

@Test
public void test1() {
	System.out.println("Spring容器开始加载....");
	ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
	User user = ac.getBean(User.class);
	System.out.println("---------------"+user);
	ac.registerShutdownHook();
	System.out.println("Spring容器卸载完成....");
}
复制代码

输出结果

Spring容器开始加载....
三月 04, 2019 11:14:38 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@707f7052: startup date [Mon Mar 04 23:14:38 CST 2019]; root of context hierarchy
三月 04, 2019 11:14:39 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
****** BeanFactoryPostProcessor 开始执行了
******* BeanFactoryPostProcessor 执行结束了
【--InstantiationAwareBeanPostProcessor----】postProcessBeforeInstantiation
构造方法被执行了...User 被实例化
【--InstantiationAwareBeanPostProcessor----】postProcessAfterInstantiation
【--InstantiationAwareBeanPostProcessor----】postProcessPropertyValues--->
《注入属性》注入name属性波波烤鸭
【BeanNameWare接口】setBeanName
【BeanFactoryAware接口】setBeanFactory
>>后置处理器 before方法:User [id=0, name=波波烤鸭, beanName=user]	user
【---InstantiationAwareBeanPostProcessor---】 postProcessBeforeInitialization
初始化:【@PostConstruct】执行了...
初始化:《InitializingBean接口》afterPropertiesSet....
初始化:【init-method】方法执行了....
<<后置处理器after方法:User [id=0, name=波波烤鸭, beanName=user]	user
【--InstantiationAwareBeanPostProcessor----】 postProcessAfterInitialization
---------------User [id=0, name=波波烤鸭, beanName=user]
Spring容器卸载完成....
三月 04, 2019 11:14:39 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@707f7052: startup date [Mon Mar 04 23:14:38 CST 2019]; root of context hierarchy
【@preDestory】执行了...
《DisposableBean接口》destroy ....
【destory-method】方法执行了....
复制代码

以上所述就是小编给大家介绍的《Spring之Bean的生命周期》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Agile Web Application Development with Yii 1.1 and PHP5

Agile Web Application Development with Yii 1.1 and PHP5

Jeffrey Winesett / Packt Publishing / 2010-08-27

In order to understand the framework in the context of a real-world application, we need to build something that will more closely resemble the types of applications web developers actually have to bu......一起来看看 《Agile Web Application Development with Yii 1.1 and PHP5》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

SHA 加密
SHA 加密

SHA 加密工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具