Bean的生命周期

文章目录

  • 什么是Bean生命周期
  • Bean生命周期的完整流程
    • [1. BeanDefinition处理阶段](#1. BeanDefinition处理阶段)
    • [2. 实例化阶段](#2. 实例化阶段)
    • [3. 属性注入阶段](#3. 属性注入阶段)
    • [4. Aware接口回调阶段](#4. Aware接口回调阶段)
    • [5. BeanPostProcessor前置处理](#5. BeanPostProcessor前置处理)
    • [6. 初始化阶段](#6. 初始化阶段)
    • [7. BeanPostProcessor后置处理](#7. BeanPostProcessor后置处理)
    • [8. Bean使用阶段](#8. Bean使用阶段)
    • [9. 销毁阶段](#9. 销毁阶段)
    • 测试类代码
  • 生命周期流程图总结

什么是Bean生命周期

Bean生命周期是指Spring容器管理Bean从创建到销毁的整个过程。

Bean生命周期的完整流程

1. BeanDefinition处理阶段

在Bean实例化之前,Spring容器需要先处理BeanDefinition相关的操作:

  • 配置元数据解析:Spring容器读取XML配置文件、Java配置类或注解,解析Bean的配置信息
  • BeanDefinition创建:将解析的配置信息封装成BeanDefinition对象
  • BeanDefinition注册:将BeanDefinition注册到BeanDefinitionRegistry中
  • BeanFactoryPostProcessor处理:在Bean实例化之前,对BeanDefinition进行修改
java 复制代码
@Component
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("BeanFactoryPostProcessor: 修改BeanDefinition");
        
        // 可以修改BeanDefinition的属性
        BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService");
        if (beanDefinition instanceof AbstractBeanDefinition) {
            // 修改作用域、懒加载等属性
            beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
        }
    }
}

2. 实例化阶段

在BeanDefinition准备完成后,Spring容器开始创建Bean实例:

  • Bean实例化:通过反射机制调用构造函数创建Bean实例
java 复制代码
@Component
public class UserService {
    public UserService() {
        System.out.println("2. UserService构造函数被调用");
    }
}

3. 属性注入阶段

在Bean实例创建完成后,Spring容器会为Bean注入依赖的属性:

  • 依赖注入:通过setter方法、字段注入或构造函数注入依赖对象
  • 属性赋值:为Bean的各个属性赋值
java 复制代码
@Component
public class UserService {
    @Autowired
    private UserRepository userRepository;
    
    @Value("${app.name}")
    private String appName;
}

4. Aware接口回调阶段

如果Bean实现了特定的Aware接口,Spring容器会调用相应的回调方法:

java 复制代码
@Component
public class UserService implements BeanNameAware {
    
    @Override
    public void setBeanName(String name) {
        System.out.println("4. BeanNameAware.setBeanName()被调用,Bean名称: " + name);
    }
}

常见的Aware接口包括:BeanNameAware、BeanFactoryAware、ApplicationContextAware等

5. BeanPostProcessor前置处理

在初始化之前,Spring容器会调用所有注册的BeanPostProcessor的postProcessBeforeInitialization方法:

java 复制代码
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("6. BeanPostProcessor.postProcessBeforeInitialization()被调用: " + beanName);
        return bean;
    }
}

6. 初始化阶段

这是Bean生命周期中的关键阶段,初始化方法的执行顺序为:

  1. @PostConstruct注解的方法
  2. InitializingBean接口的afterPropertiesSet()方法
  3. 自定义的init-method方法
java 复制代码
@Component
public class UserService implements InitializingBean {
    
    @PostConstruct
    public void postConstruct() {
        System.out.println("7. @PostConstruct注解的方法被调用");
    }
    
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("8. InitializingBean.afterPropertiesSet()被调用");
    }
    
    public void customInit() {
        System.out.println("9. 自定义init方法被调用");
    }
}

配置自定义init方法:

java 复制代码
@Configuration
public class AppConfig {
    
    @Bean(initMethod = "customInit")
    public UserService userService() {
        return new UserService();
    }
}

7. BeanPostProcessor后置处理

初始化完成后,Spring容器会调用所有注册的BeanPostProcessor的postProcessAfterInitialization方法:

java 复制代码
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
    
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("10. BeanPostProcessor.postProcessAfterInitialization()被调用: " + beanName);
        return bean;
    }
}

BeanPostProcessor是Spring框架的核心扩展点之一,它的主要作用包括:

  1. AOP代理创建:Spring AOP通过BeanPostProcessor在初始化后创建代理对象
  2. Bean增强:对Bean进行包装、修改或替换
  3. 属性修改:在Bean初始化前后修改Bean的属性

8. Bean使用阶段

经过上述步骤后,Bean已经完全初始化并注册到单例池中,在这个阶段,Bean处于就绪状态,可以处理业务逻辑,后续对该Bean的获取都会直接从单例池中返回同一个实例。

9. 销毁阶段

当Spring容器关闭时,会销毁所有的单例Bean。销毁方法的执行顺序为:

  1. @PreDestroy注解的方法
  2. DisposableBean接口的destroy()方法
  3. 自定义的destroy-method方法
java 复制代码
@Component
public class UserService implements DisposableBean {
    
    @PreDestroy
    public void preDestroy() {
        System.out.println("11. @PreDestroy注解的方法被调用");
    }
    
    @Override
    public void destroy() throws Exception {
        System.out.println("12. DisposableBean.destroy()被调用");
    }
    
    public void customDestroy() {
        System.out.println("13. 自定义destroy方法被调用");
    }
}

测试类代码

java 复制代码
public class UserServiceTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = 
            new AnnotationConfigApplicationContext(AppConfig.class);
        
        UserService bean = context.getBean(UserService .class);
        bean.doSomething();
        
        // 关闭容器,触发销毁过程
        context.close();
    }
}

生命周期流程图总结

Bean的完整生命周期可以用以下流程概括:

复制代码
BeanDefinition处理 → BeanFactoryPostProcessor处理 → Bean实例化 → 属性注入 → Aware接口回调 → 
BeanPostProcessor前置处理 → 初始化方法 → BeanPostProcessor后置处理 → Bean就绪可使用 → 销毁方法 

声明 :本文结合了AI和学者的知识理解,在AI生成的文章框架的基础上补充完成的。

掌握Bean生命周期不仅有助于日常开发,更是深入学习Spring框架源码和高级特性的基础。希望本文能够帮助大家更好地理解和应用Spring Bean的生命周期。

相关推荐
卓码软件测评30 分钟前
网站测评-利用缓存机制实现XSS的分步测试方法
java·后端·安全·spring·可用性测试·软件需求
Skylar_.1 小时前
嵌入式 - Linux软件编程:进程
java·linux·服务器
Acrelhuang2 小时前
基于柔性管控终端的新能源汽车充电站有序充电系统设计与实现
java·开发语言·人工智能
召唤神龙2 小时前
Java如何设置代理IP:详细教程与实用代码示例
java
程序员二黑2 小时前
手把手搭建自动化测试环境:10分钟搞定Python/Java双环境
java·python·测试
字节跳跃者2 小时前
SpringBoot 实现动态切换数据源,这样做才更优雅!
java·后端
ruangongtaotao3 小时前
java python
java·开发语言·python
天天摸鱼的java工程师3 小时前
SpringCloud + Sentinel + Resilience4j:微服务熔断降级策略的设计与实践
java·后端
Neo2553 小时前
Spring 5.3.x 源码:基础构建
spring