spring bean生命周期

本文详细剖析了Spring Bean从实例化到销毁的完整生命周期,包括BeanFactoryPostProcessor、BeanPostProcessor、InstantiationAwareBeanPostProcessorAdapter等接口的执行顺序,以及@PostConstruct、@PreDestroy注解和InitializingBean、DisposableBean接口的使用。通过实例和注意事项,阐述了Bean初始化和销毁的三种主要方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、分析
(1)实例化BeanFactoryPostProcessor实现类,执行BeanFactoryPostProcessor实现类的postProcessBeanFactory方法
(2)实例化BeanPostProcessor【后置处理器】实现类
(3)实例化InstantiationAwareBeanPostProcessorAdapter实现类,执行postProcessBeforeInstantiation方法,其中InstantiationAwareBeanPostProcessor是BeanPostProcessor子接口,bean实例化之前执行
(4)执行bean构造器
(5)执行InstantiationAwareBeanPostProcessorAdapter实现类的postProcessAfterInstantiation方法,其中InstantiationAwareBeanPostProcessor是BeanPostProcessor子接口,bean属性注入之后执行
(6)执行InstantiationAwareBeanPostProcessorAdapter实现类的postProcessPropertyValues方法,其中InstantiationAwareBeanPostProcessor是BeanPostProcessor子接口,bean实例化之后执行
(7)为bean注入属性
(8)调用BeanNameAware的setBeanName方法,这个可以获取bean在BeanFactory中定义的名字
(9)调用BeanFactoryAware的setBeanFactory方法,这个可以获得到BeanFactory
(10)执行BeanPostProcessor【后置处理器】实现类的postProcessBeforeInitialization方法
(11)执行JSR250规范的@PostConstruct注解方法,然后执行InitializingBean实现类的afterPropertiesSet方法
(12)调用bean指定的init-method方法
(13)执行BeanPostProcessor【后置处理器】实现类的postProcessAfterInitialization方法
(14)容器初始化成功,执行正常调用,以下开始销毁
(15)执行JSR250规范的@PreDestroy注解方法,执行DisposableBean实现类的destroy方法
(16)调用bean指定的destroy-method方法
(17)销毁成功

二、实例

package com.zhy.stest;

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;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * <p>
 * User测试
 * </p>
 *
 * @author ythu
 * @datetime 2018年6月6日 下午2:41:48
 */
public class User implements InitializingBean, DisposableBean, BeanNameAware, BeanFactoryAware, ApplicationContextAware {

	private int id;

	public User() {
		super();
		System.out.println("无参数构造器User.User()");
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		System.out.println("注入属性User.setId()");
		this.id = id;
	}

	public void initMethod() {
		System.out.println("初始化User.initMethod()");
	}

	public void destroyMethod() {
		System.out.println("销毁User.destroyMethod()");
	}

	public void afterPropertiesSet() throws Exception {
		System.out.println("初始化User.afterPropertiesSet()");
	}

	public void destroy() throws Exception {
		System.out.println("销毁User.destroy()");
	}

	public void setBeanName(String name) {
		System.out.println("BeanNameAware执行了" + name);
	}

	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		System.out.println("BeanFactoryAware执行了" + beanFactory.toString());
	}

	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		System.out.println("ApplicationContextAware执行了" + applicationContext.toString());
	}
}

 

package com.zhy.stest;

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;

/**
 * <p>
 * 容器后置处理器
 * </p>
 *
 * @author ythu
 * @datetime 2018年6月6日 下午3:15:05
 */
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

	/**
	 * 可以在spring的bean创建之前,修改bean的定义属性;
	 */
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		System.out.println("MyBeanFactoryPostProcessor.postProcessBeanFactory()");
		BeanDefinition beanDefinition = beanFactory.getBeanDefinition("user");
		MutablePropertyValues mutablePropertyValues = beanDefinition.getPropertyValues();
		if (mutablePropertyValues.contains("id")) {
			mutablePropertyValues.addPropertyValue("id", 2);
		}
	}
}
package com.zhy.stest;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

/**
 * <p>
 * bean后置处理器
 * </p>
 *
 * @author ythu
 * @datetime 2018年6月6日 下午3:14:28
 */
public class MyBeanPostProcessor implements BeanPostProcessor {

	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("postProcessBeforeInitialization:" + bean + "," + beanName);
		return bean;
	}

	/**
	 * bean初始化之后执行
	 */
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("postProcessAfterInitialization:" + bean + "," + beanName);
		return bean;
	}

}

 

package com.zhy.stest;

import java.beans.PropertyDescriptor;

import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;

/**
 * <p>
 * bean实例化后缀处理器
 * </p>
 *
 * @author ythu
 * @datetime 2018年6月6日 下午4:03:49
 */
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

	/**
	 * BeanPostProcessor来自这个父接口
	 */
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("MyInstantiationAwareBeanPostProcessor.postProcessBeforeInitialization()");
		return bean;
	}

	/**
	 * BeanPostProcessor来自这个父接口
	 */
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("MyInstantiationAwareBeanPostProcessor.postProcessAfterInitialization()");
		return bean;
	}

	/**
	 * bean实例化之前
	 */
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		System.out.println("MyInstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()");
		return null;
	}

	/**
	 * bean实例化之后
	 */
	public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		System.out.println("MyInstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()");
		return true;
	}

	/**
	 * 属性注入之前
	 */
	public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
		System.out.println("MyInstantiationAwareBeanPostProcessor.postProcessPropertyValues()");
		return pvs;
	}
}
<?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">
    
    <bean class="com.zhy.stest.MyBeanFactoryPostProcessor"></bean>
    <bean class="com.zhy.stest.MyBeanPostProcessor"></bean>
    <bean class="com.zhy.stest.MyInstantiationAwareBeanPostProcessor"></bean>

	<bean id="user" class="com.zhy.stest.User" init-method="initMethod" destroy-method="destroyMethod">
		<property name="id" value="1" />
	</bean>
</beans>

 

public class UserTest {
	public static void main(String[] args) {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("springContext.xml");
		User user = context.getBean(User.class);
		System.out.println(user.getId());
		context.close();
	}
}
六月 06, 2018 5:15:09 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@5a6b258d: startup date [Wed Jun 06 17:15:09 CST 2018]; root of context hierarchy
六月 06, 2018 5:15:09 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [springContext.xml]
MyBeanFactoryPostProcessor.postProcessBeanFactory()
MyInstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
无参数构造器User.User()
MyInstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
MyInstantiationAwareBeanPostProcessor.postProcessPropertyValues()
注入属性User.setId()
BeanNameAware执行了user
BeanFactoryAware执行了org.springframework.beans.factory.support.DefaultListableBeanFactory@4cfdf5ef: defining beans [com.zhy.stest.MyBeanFactoryPostProcessor#0,com.zhy.stest.MyBeanPostProcessor#0,com.zhy.stest.MyInstantiationAwareBeanPostProcessor#0,user]; root of factory hierarchy
ApplicationContextAware执行了org.springframework.context.support.ClassPathXmlApplicationContext@5a6b258d: startup date [Wed Jun 06 17:15:09 CST 2018]; root of context hierarchy
postProcessBeforeInitialization:com.zhy.stest.User@1487be2a,user
MyInstantiationAwareBeanPostProcessor.postProcessBeforeInitialization()
初始化User.afterPropertiesSet()
初始化User.initMethod()
postProcessAfterInitialization:com.zhy.stest.User@1487be2a,user
MyInstantiationAwareBeanPostProcessor.postProcessAfterInitialization()
2
六月 06, 2018 5:15:09 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@5a6b258d: startup date [Wed Jun 06 17:15:09 CST 2018]; root of context hierarchy
销毁User.destroy()
销毁User.destroyMethod() 

三、注意

注意bean的初始化和销毁方式有以下三种:
1.实现InitializingBean和DisposableBean接口
这两个接口都只包含一个方法。通过实现InitializingBean接口的afterPropertiesSet方法可以在Bean属性值设置好之后做一些操作,实现DisposableBean接口的destroy方法可以在销毁Bean之前做一些操作。
2.在bean的配置文件中指定init-method和destroy-method方法
Spring允许我们创建自己的init方法和destroy方法,只要在Bean的配置文件中指定init-method和destroy-method的值就可以在Bean初始化时和销毁之前执行一些操作。
3.使用@PostConstruct和@PreDestroy注解
除了xml配置的方式,Spring也支持用@PostConstruct和 @PreDestroy注解来指定init和destroy方法。这两个注解均在javax.annotation包中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值