Spring Bean的生命周期是指Bean从创建到销毁的完整过程。与普通Java对象不同,Spring Bean由IoC容器管理,经历了一系列复杂的阶段。Bean定义Bean实例化Bean初始化Bean使用和Bean销毁`这几个主要阶段。在Spring容器中,Bean的生命周期远比该简单概述要复杂得多。实际上,一个Bean从创建到销毁,要经历十多个阶段,每个阶段都有相应的扩展
引言
在Spring框架中,Bean是构建应用程序的基础单元,它们由Spring IoC容器进行管理。理解Spring Bean的生命周期对于有效利用Spring框架、解决常见问题以及进行高级定制至关重要。
一、Spring Bean生命周期概述
Spring Bean的生命周期是指Bean从创建到销毁的完整过程。与普通Java对象不同,Spring Bean由IoC容器管理,经历了一系列复杂的阶段。简单来说,Bean的生命周期可以概括为:Bean定义、Bean实例化、Bean初始化、Bean使用和Bean销毁`这几个主要阶段。
在Spring容器中,Bean的生命周期远比这个简单概述要复杂得多。实际上,一个Bean从创建到销毁,要经历十多个阶段,每个阶段都有相应的扩展点,允许开发者介入并自定义Bean的行为。
二、Spring Bean生命周期的详细阶段
1. Bean元信息配置阶段
这是Bean生命周期的起点,主要涉及Bean定义信息的配置。Spring支持多种方式来配置Bean的元信息:
1.1 面向资源的配置方式
XML配置方式:
<bean id="userService" class="com.example.service.UserServiceImpl">
<property name="userDao" ref="userDao"/>
</bean>
Properties资源配置方式:
user.service.class=com.example.service.UserServiceImpl
user.service.property.userDao=userDao
1.2 面向注解的配置方式
@Component
public class UserServiceImpl
implements UserService {
@Autowired
private UserDao userDao;
// ...
}
1.3 面向API的配置方式
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(UserServiceImpl.class)
;
builder.addPropertyReference("userDao", "userDao");
BeanDefinition definition = builder.getBeanDefinition();
registry.registerBeanDefinition("userService", definition);
2. Bean元信息解析阶段
在这个阶段,Spring会解析上一阶段配置的Bean元信息,主要包括:
2.1 面向资源BeanDefinition解析
- 通过
BeanDefinitionReader接口实现 - XML解析器使用
BeanDefinitionParser
2.2 面向注解BeanDefinition解析
- 通过
AnnotatedBeanDefinitionReader实现
3. Bean注册阶段
解析后的BeanDefinition会被注册到Spring容器中,这一过程通过BeanDefinitionRegistry接口完成:
public interface BeanDefinitionRegistry extends AliasRegistry {
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException;
// 其他方法...
}
DefaultListableBeanFactory是BeanDefinitionRegistry的主要实现类,它维护了一个ConcurrentHashMap来存储所有的BeanDefinition。
4. BeanDefinition合并阶段
如果Bean有父定义,这个阶段会将父子BeanDefinition进行合并:
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
合并过程会考虑:
- 当前BeanFactory中的查找
- 层次性BeanFactory的查找
5. Bean实例化前阶段
在Bean实例化之前,Spring提供了一个扩展点,允许开发者介入实例化过程:
@Component
public class MyInstantiationAwareBeanPostProcessor
implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<
?> beanClass, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
// 返回代理对象
return new UserServiceProxy();
}
return null;
// 继续正常实例化
}
}
如果postProcessBeforeInstantiation方法返回非null对象,将跳过后续的实例化过程,直接使用返回的对象。
6. Bean实例化阶段
这是创建Bean实例的阶段,主要涉及:
实例化方式
- 传统实例化方式:通过实例化策略(InstantiationStrategy)
- 构造器依赖注入方式:根据构造函数参数解析并注入依赖
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 确定要实例化的类
Class<
?> beanClass = resolveBeanClass(mbd, beanName);
// 使用合适的实例化策略创建新的实例:工厂方法、构造函数自动注入、简单实例化
if (mbd.getFactoryMethodName() != null) {
// 通过工厂方法实例化
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 构造函数自动注入
ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// 使用默认构造函数实例化
return instantiateBean(beanName, mbd);
}
7. Bean实例化后阶段
Bean实例化后,Spring提供了另一个扩展点:
@Component
public class MyInstantiationAwareBeanPostProcessor
implements InstantiationAwareBeanPostProcessor {
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
// 对实例化后的Bean进行一些处理
System.out.println("Bean '" + beanName + "' 已实例化");
}
return true;
// 继续属性填充
}
}
如果postProcessAfterInstantiation方法返回false,将跳过后续的属性填充过程。
8. Bean属性赋值前阶段
在属性被设置到Bean之前,Spring提供了处理属性值的机会:
@Component
public class MyInstantiationAwareBeanPostProcessor
implements InstantiationAwareBeanPostProcessor {
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
// 修改或添加属性值
MutablePropertyValues mpvs = new MutablePropertyValues(pvs);
mpvs.add("customProperty", "customValue");
return mpvs;
}
return pvs;
}
}
9. Bean属性赋值阶段
这个阶段Spring会将属性值设置到Bean实例中,包括:
- 依赖注入(通过@Autowired、@Resource等注解)
- 属性设置(通过setter方法或直接字段访问)
10. Bean Aware接口回调阶段
如果Bean实现了Aware系列接口,Spring会在这个阶段调用相应的方法:
public class UserService
implements BeanNameAware, BeanFactoryAware {
private String beanName;
private BeanFactory beanFactory;
@Override
public void setBeanName(String name) {
this.beanName = name;
System.out.println("Bean名称: " + name);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
System.out.println("BeanFactory: " + beanFactory);
}
}
Spring提供了多种Aware接口:
- BeanNameAware:获取Bean名称
- BeanClassLoaderAware:获取ClassLoader
- BeanFactoryAware:获取BeanFactory
- EnvironmentAware:获取Environment
- EmbeddedValueResolverAware:获取StringValueResolver
- ResourceLoaderAware:获取资源加载器
- ApplicationEventPublisherAware:获取事件发布器
- MessageSourceAware:获取消息源
- ApplicationContextAware:获取应用上下文
11. Bean初始化前阶段
在Bean初始化之前,Spring会调用BeanPostProcessor的前置处理方法:
@Component
public class MyBeanPostProcessor
implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
System.out.println("初始化前处理: " + beanName);
// 可以返回原始Bean或包装后的Bean
}
return bean;
}
}
12. Bean初始化阶段
这个阶段包括三种初始化方式,按照以下顺序执行:
12.1 @PostConstruct注解标注的方法
@Component
public class UserService
{
@PostConstruct
public void init() {
System.out.println("@PostConstruct初始化方法");
}
}
12.2 实现InitializingBean接口的afterPropertiesSet方法
@Component
public class UserService
implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean#afterPropertiesSet初始化方法");
}
}
12.3 自定义初始化方法
XML配置:
<bean id="userService" class="com.example.service.UserServiceImpl" init-method="customInit"/>
Java配置:
@Bean(initMethod = "customInit")
public UserService userService() {
return new UserServiceImpl();
}
实现类:
public class UserServiceImpl
{
public void customInit() {
System.out.println("自定义初始化方法");
}
}
13. Bean初始化后阶段
在Bean初始化之后,Spring会调用BeanPostProcessor的后置处理方法:
@Component
public class MyBeanPostProcessor
implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
System.out.println("初始化后处理: " + beanName);
// 可以返回原始Bean或包装后的Bean
}
return bean;
}
}
这个阶段常用于创建代理对象,例如Spring AOP就是在这个阶段创建代理的。
14. Bean初始化完成阶段
所有单例Bean初始化完成后,Spring会调用SmartInitializingSingleton接口的方法:
@Component
public class UserService
implements SmartInitializingSingleton {
@Override
public void afterSingletonsInstantiated() {
System.out.println("所有单例Bean初始化完成后调用");
}
}
或者使用事件监听方式:
@Component
public class UserService
implements ApplicationListener<
ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
System.out.println("上下文刷新事件");
}
}
15. Bean销毁前阶段
在Bean销毁之前,Spring会调用DestructionAwareBeanPostProcessor接口的方法:
@Component
public class MyDestructionAwareBeanPostProcessor
implements DestructionAwareBeanPostProcessor {
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
System.out.println("销毁前处理: " + beanName);
}
}
}
16. Bean销毁阶段
这个阶段包括三种销毁方式,按照以下顺序执行:
16.1 @PreDestroy注解标注的方法
@Component
public class UserService
{
@PreDestroy
public void preDestroy() {
System.out.println("@PreDestroy销毁方法");
}
}
16.2 实现DisposableBean接口的destroy方法
@Component
public class UserService
implements DisposableBean {
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean#destroy销毁方法");
}
}
16.3 自定义销毁方法
XML配置:
<bean id="userService" class="com.example.service.UserServiceImpl" destroy-method="customDestroy"/>
Java配置:
@Bean(destroyMethod = "customDestroy")
public UserService userService() {
return new UserServiceImpl();
}
实现类:
public class UserServiceImpl
{
public void customDestroy() {
System.out.println("自定义销毁方法");
}
}
17. Bean垃圾回收
当Spring容器关闭,并且没有其他引用指向Bean实例时,Bean就可以被垃圾回收了。如果Bean覆盖了finalize方法,该方法会在垃圾回收时被调用。
三、Spring Bean生命周期图解
Spring Bean的生命周期可以用下图来表示:
┌─────────────────────────────┐
│ BeanDefinition配置与解析 │
└───────────────┬─────────────┘
↓
┌─────────────────────────────┐
│ BeanDefinition注册 │
└───────────────┬─────────────┘
↓
┌─────────────────────────────┐
│ BeanDefinition合并 │
└───────────────┬─────────────┘
↓
┌─────────────────────────────┐
│ Bean实例化前处理 │
└───────────────┬─────────────┘
↓
┌─────────────────────────────┐
│ Bean实例化 │
└───────────────┬─────────────┘
↓
┌─────────────────────────────┐
│ Bean实例化后处理 │
└───────────────┬─────────────┘
↓
┌─────────────────────────────┐
│ Bean属性赋值前处理 │
└───────────────┬─────────────┘
↓
┌─────────────────────────────┐
│ Bean属性赋值 │
└───────────────┬─────────────┘
↓
┌─────────────────────────────┐
│ Bean Aware接口回调 │
└───────────────┬─────────────┘
↓
┌─────────────────────────────┐
│ Bean初始化前处理 │
└───────────────┬─────────────┘
↓
┌─────────────────────────────┐
│ Bean初始化 │
│ 1. @PostConstruct │
│ 2. InitializingBean │
│ 3. 自定义初始化方法 │
└───────────────┬─────────────┘
↓
┌─────────────────────────────┐
│ Bean初始化后处理 │
└───────────────┬─────────────┘
↓
┌─────────────────────────────┐
│ Bean初始化完成处理 │
└───────────────┬─────────────┘
↓
┌─────────────────────────────┐
│ Bean使用 │
└───────────────┬─────────────┘
↓
┌─────────────────────────────┐
│ Bean销毁前处理 │
└───────────────┬─────────────┘
↓
┌─────────────────────────────┐
│ Bean销毁 │
│ 1. @PreDestroy │
│ 2. DisposableBean │
│ 3. 自定义销毁方法 │
└───────────────┬─────────────┘
↓
┌─────────────────────────────┐
│ Bean垃圾回收 │
└─────────────────────────────┘
四、完整代码示例
下面是一个完整的示例,展示了Spring Bean生命周期的各个阶段:
package com.example.lifecycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.BeanClassLoaderAware;
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.beans.factory.SmartInitializingSingleton;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@Component
public class LifecycleDemoBean
implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware,
ApplicationContextAware, InitializingBean, DisposableBean,
SmartInitializingSingleton, ApplicationListener<
ContextRefreshedEvent> {
private String beanName;
// 1. 实例化
public LifecycleDemoBean() {
System.out.println("1. 构造函数 - Bean实例化");
}
// 2. BeanNameAware接口回调
@Override
public void setBeanName(String name) {
this.beanName = name;
System.out.println("2. BeanNameAware接口回调 - Bean名称: " + name);
}
// 3. BeanClassLoaderAware接口回调
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("3. BeanClassLoaderAware接口回调 - ClassLoader: " + classLoader);
}
// 4. BeanFactoryAware接口回调
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("4. BeanFactoryAware接口回调 - BeanFactory: " + beanFactory);
}
// 5. ApplicationContextAware接口回调
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("5. ApplicationContextAware接口回调 - ApplicationContext: " + applicationContext);
}
// 6. @PostConstruct注解标注的初始化方法
@PostConstruct
public void postConstruct() {
System.out.println("6. @PostConstruct注解标注的初始化方法");
}
// 7. InitializingBean接口的初始化方法
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("7. InitializingBean接口的afterPropertiesSet方法");
}
// 8. 自定义初始化方法
public void customInit() {
System.out.println("8. 自定义初始化方法");
}
// 9. SmartInitializingSingleton接口回调
@Override
public void afterSingletonsInstantiated() {
System.out.println("9. SmartInitializingSingleton接口的afterSingletonsInstantiated方法");
}
// 10. ApplicationListener接口回调
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
System.out.println("10. ApplicationListener接口的onApplicationEvent方法 - 事件: " + event);
}
// 11. 业务方法
public void businessMethod() {
System.out.println("11. 业务方法 - Bean正在使用中");
}
// 12. @PreDestroy注解标注的销毁方法
@PreDestroy
public void preDestroy() {
System.out.println("12. @PreDestroy注解标注的销毁方法");
}
// 13. DisposableBean接口的销毁方法
@Override
public void destroy() throws Exception {
System.out.println("13. DisposableBean接口的destroy方法");
}
// 14. 自定义销毁方法
public void customDestroy() {
System.out.println("14. 自定义销毁方法");
}
// 15. finalize方法
@Override
protected void finalize() throws Throwable {
System.out.println("15. finalize方法 - Bean被垃圾回收");
super.finalize();
}
}
BeanPostProcessor实现:
@Component
public class CustomBeanPostProcessor
implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof LifecycleDemoBean) {
System.out.println("BeanPostProcessor#postProcessBeforeInitialization - Bean: " + beanName);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof LifecycleDemoBean) {
System.out.println("BeanPostProcessor#postProcessAfterInitialization - Bean: " + beanName);
}
return bean;
}
}
InstantiationAwareBeanPostProcessor实现:
@Component
public class CustomInstantiationAwareBeanPostProcessor
implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<
?> beanClass, String beanName) throws BeansException {
if (LifecycleDemoBean.class.
equals(beanClass)) {
System.out.println("InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation - Bean: " + beanName);
}
return null;
// 返回null表示使用默认实例化过程
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if (bean instanceof LifecycleDemoBean) {
System.out.println("InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation - Bean: " + beanName);
}
return true;
// 返回true表示继续属性填充
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if (bean instanceof LifecycleDemoBean) {
System.out.println("InstantiationAwareBeanPostProcessor#postProcessProperties - Bean: " + beanName);
}
return pvs;
}
}
DestructionAwareBeanPostProcessor实现:
@Component
public class CustomDestructionAwareBeanPostProcessor
implements DestructionAwareBeanPostProcessor {
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
if (bean instanceof LifecycleDemoBean) {
System.out.println("DestructionAwareBeanPostProcessor#postProcessBeforeDestruction - Bean: " + beanName);
}
}
@Override
public boolean requiresDestruction(Object bean) {
return bean instanceof LifecycleDemoBean;
}
}
配置类:
@Configuration
@ComponentScan("com.example.lifecycle")
public class AppConfig
{
@Bean(initMethod = "customInit", destroyMethod = "customDestroy")
public LifecycleDemoBean lifecycleDemoBean() {
return new LifecycleDemoBean();
}
}
主类:
public class LifecycleDemo
{
public static void main(String[] args) {
// 创建Spring容器
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class)
;
// 获取Bean
LifecycleDemoBean bean = context.getBean(LifecycleDemoBean.class)
;
// 使用Bean
bean.businessMethod();
// 关闭容器,触发Bean销毁
context.close();
// 建议GC
bean = null;
System.gc();
}
}
五、常见问题与解答
1. BeanPostProcessor的使用场景有哪些?
BeanPostProcessor提供Spring Bean初始化前和初始化后的生命周期回调,分别对应postProcessBeforeInitialization以及postProcessAfterInitialization方法,允许对关心的Bean进行扩展,甚至是替换。
常见使用场景包括:
- 创建代理对象(如Spring AOP)
- 处理注解(如@Autowired、@PostConstruct等)
- 修改Bean属性
- 替换Bean实例
值得一提的是,ApplicationContext相关的Aware回调也是基于BeanPostProcessor实现的,即ApplicationContextAwareProcessor。
2. BeanFactoryPostProcessor与BeanPostProcessor的区别?
BeanFactoryPostProcessor是Spring BeanFactory(实际为ConfigurableListableBeanFactory)的后置处理器,用于扩展BeanFactory,或通过BeanFactory进行依赖查找和依赖注入。BeanFactoryPostProcessor必须由Spring ApplicationContext执行,BeanFactory无法与其直接交互。
而BeanPostProcessor则直接与BeanFactory关联,属于N对1的关系。
主要区别:
- BeanFactoryPostProcessor操作的是BeanDefinition,在Bean实例化之前执行
- BeanPostProcessor操作的是Bean实例,在Bean实例化之后执行
- BeanFactoryPostProcessor先于BeanPostProcessor执行
3. 单例Bean和原型Bean的生命周期有什么区别?
单例Bean(Singleton):
- 在容器启动时就会实例化(懒加载除外)
- 整个应用中只有一个实例
- 完整经历从创建到销毁的生命周期
- 容器关闭时会执行销毁回调
原型Bean(Prototype):
- 每次请求时才会创建新实例
- 每个请求都会得到一个新的实例
- 只经历创建阶段,不会执行销毁回调
- Spring不会管理其完整生命周期,不会调用销毁方法
4. @PostConstruct和InitializingBean接口的区别?
两者都用于Bean的初始化,但有以下区别:
- @PostConstruct是JSR-250规范的注解,不依赖于Spring框架
- InitializingBean是Spring特有的接口,与Spring框架耦合
- @PostConstruct标注的方法会先于InitializingBean的afterPropertiesSet方法执行
- @PostConstruct更加灵活,可以标注多个方法,而InitializingBean只能实现一个方法
一般推荐使用@PostConstruct,因为它不会使代码与Spring框架耦合。
5. 如何自定义Bean的作用域?
Spring默认提供了singleton、prototype、request、session等作用域,但有时我们需要自定义作用域。可以通过实现Scope接口来自定义Bean的作用域:
public class CustomScope
implements Scope {
private final Map<
String, Object> scopedObjects = new ConcurrentHashMap<
>();
@Override
public Object get(String name, ObjectFactory<
?> objectFactory) {
if (!scopedObjects.containsKey(name)) {
scopedObjects.put(name, objectFactory.getObject());
}
return scopedObjects.get(name);
}
@Override
public Object remove(String name) {
return scopedObjects.remove(name);
}
@Override
public void registerDestructionCallback(String name, Runnable callback) {
// 注册销毁回调
}
@Override
public Object resolveContextualObject(String key) {
return null;
}
@Override
public String getConversationId() {
return "custom";
}
}
然后注册自定义作用域:
@Configuration
public class AppConfig
implements ApplicationContextAware {
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
ConfigurableBeanFactory beanFactory = ((ConfigurableApplicationContext) applicationContext).getBeanFactory();
beanFactory.registerScope("custom", new CustomScope());
}
@Bean
@Scope("custom")
public SomeBean someBean() {
return new SomeBean();
}
}
六、总结
Spring Bean的生命周期是一个复杂而精密的过程,涉及多个阶段和扩展点。理解这些阶段和扩展点对于高效使用Spring框架至关重要。
在实际应用中,我们通常不需要关注所有的生命周期阶段,而是根据需要选择合适的扩展点。最常用的扩展点包括:
- @PostConstruct和@PreDestroy注解:用于初始化和销毁Bean
- BeanPostProcessor接口:用于在Bean初始化前后进行处理
- Aware接口:用于获取Spring容器中的各种资源
通过合理利用这些扩展点,我们可以灵活地定制Bean的行为,满足各种复杂的业务需求。

浙公网安备 33010602011771号