bean 的生命周期

Bean 的生命周期详解

在 Spring 框架中,Bean 的生命周期是一个非常重要的概念。理解 Bean 的生命周期有助于我们更好地使用 Spring,包括如何初始化资源、如何清理资源以及如何自定义 Bean 的创建过程。

一、Bean 生命周期的核心阶段

Spring 容器中 Bean 的生命周期可以概括为以下几个主要阶段:

  1. 实例化:创建 Bean 的实例(通过构造器或工厂方法)
  2. 属性赋值:设置 Bean 的属性值(依赖注入)
  3. 初始化:执行初始化方法
  4. 使用:Bean 可以被应用程序使用
  5. 销毁:容器关闭时执行销毁方法

二、生命周期的详细过程

下面是一个更详细的流程图,展示了 Bean 从创建到销毁的完整过程:

plaintext

Bean定义注册到容器 → 实例化Bean → 填充属性 → 
实现Aware接口的方法调用 → BeanPostProcessor前置处理 → 
初始化方法调用 → BeanPostProcessor后置处理 → 
Bean就绪可以使用 → 容器关闭 → 销毁方法调用

三、关键接口和方法

1. 实例化相关

  • InstantiationAwareBeanPostProcessor
    • 可以在实例化前和实例化后进行干预
    • 方法:postProcessBeforeInstantiation 和 postProcessAfterInstantiation

2. 属性赋值相关

  • AutowiredAnnotationBeanPostProcessor
    • 处理 @Autowired、@Resource 等注解
  • CommonAnnotationBeanPostProcessor
    • 处理 JSR-250 注解如 @PostConstruct、@PreDestroy

3. Aware 接口

Spring 提供了一系列 Aware 接口,允许 Bean 获取容器的相关信息:

  • BeanNameAware:获取 Bean 在容器中的名称
  • BeanFactoryAware:获取 BeanFactory
  • ApplicationContextAware:获取 ApplicationContext
  • ResourceLoaderAware:获取资源加载器
  • ServletContextAware(仅 Web 应用):获取 ServletContext

4. 初始化相关

初始化方法可以通过以下三种方式指定:

  1. 实现 InitializingBean 接口:javapublic class MyBean implements InitializingBean { @Override public void afterPropertiesSet() throws Exception { // 初始化逻辑 } }
  2. 使用 @PostConstruct 注解:javapublic class MyBean { @PostConstruct public void init() { // 初始化逻辑 } }
  3. 在 XML 配置或 @Bean 注解中指定 init-method:java@Bean(initMethod = "init") public MyBean myBean() { return new MyBean(); }

5. BeanPostProcessor

BeanPostProcessor 允许在 Bean 初始化前后进行额外处理:

java

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // 在初始化方法调用前执行
        return bean;
    }
    
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // 在初始化方法调用后执行
        return bean;
    }
}

6. 销毁相关

销毁方法可以通过以下三种方式指定:

  1. 实现 DisposableBean 接口:javapublic class MyBean implements DisposableBean { @Override public void destroy() throws Exception { // 资源释放逻辑 } }
  2. 使用 @PreDestroy 注解:javapublic class MyBean { @PreDestroy public void cleanup() { // 资源释放逻辑 } }
  3. 在 XML 配置或 @Bean 注解中指定 destroy-method:java@Bean(destroyMethod = "cleanup") public MyBean myBean() { return new MyBean(); }

四、自定义生命周期处理器

除了上述标准方法外,还可以通过以下方式自定义 Bean 的生命周期:

1. BeanFactoryPostProcessor

允许在 Bean 定义加载后但实例化前修改 Bean 定义:

java

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // 修改Bean定义
        BeanDefinition beanDefinition = beanFactory.getBeanDefinition("myBean");
        beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
    }
}

2. DestructionAwareBeanPostProcessor

可以在 Bean 销毁前进行额外处理:

java

@Component
public class MyDestructionAwareBeanPostProcessor implements DestructionAwareBeanPostProcessor {
    @Override
    public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
        // 在销毁前执行
    }
    
    @Override
    public boolean requiresDestruction(Object bean) {
        return true;
    }
}

五、示例代码

下面是一个完整的示例,展示了一个 Bean 的生命周期:

java

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class MyBean implements BeanNameAware, ApplicationContextAware, InitializingBean {

    private String name;
    private ApplicationContext applicationContext;

    // 构造器
    public MyBean() {
        System.out.println("MyBean: 构造器被调用");
    }

    // Setter方法(依赖注入)
    public void setName(String name) {
        System.out.println("MyBean: 设置name属性");
        this.name = name;
    }

    // BeanNameAware接口方法
    @Override
    public void setBeanName(String beanName) {
        System.out.println("MyBean: 实现BeanNameAware,获取bean名称: " + beanName);
    }

    // ApplicationContextAware接口方法
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("MyBean: 实现ApplicationContextAware,获取应用上下文");
        this.applicationContext = applicationContext;
    }

    // @PostConstruct注解的初始化方法
    @PostConstruct
    public void postConstructInit() {
        System.out.println("MyBean: @PostConstruct注解的初始化方法被调用");
    }

    // InitializingBean接口方法
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("MyBean: 实现InitializingBean,afterPropertiesSet方法被调用");
    }

    // 自定义初始化方法
    public void customInit() {
        System.out.println("MyBean: 自定义init-method方法被调用");
    }

    // @PreDestroy注解的销毁方法
    @PreDestroy
    public void preDestroy() {
        System.out.println("MyBean: @PreDestroy注解的销毁方法被调用");
    }

    // DisposableBean接口方法
    public void destroy() throws Exception {
        System.out.println("MyBean: 实现DisposableBean,destroy方法被调用");
    }

    // 自定义销毁方法
    public void customDestroy() {
        System.out.println("MyBean: 自定义destroy-method方法被调用");
    }

    // 业务方法
    public void doSomething() {
        System.out.println("MyBean: 执行doSomething方法");
    }
}

配置类:

java

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {
    
    @Bean(initMethod = "customInit", destroyMethod = "customDestroy")
    public MyBean myBean() {
        MyBean bean = new MyBean();
        bean.setName("TestBean");
        return bean;
    }
}

六、生命周期总结

Bean 的完整生命周期可以概括为:

  1. 实例化:通过构造器创建 Bean 对象
  2. 依赖注入:设置 Bean 的属性值
  3. Aware 接口回调:如果实现了 Aware 接口,调用相应的方法
  4. BeanPostProcessor 前置处理:调用所有注册的 BeanPostProcessor 的前置处理方法
  5. 初始化方法调用:按顺序调用 @PostConstruct、InitializingBean 接口方法、自定义初始化方法
  6. BeanPostProcessor 后置处理:调用所有注册的 BeanPostProcessor 的后置处理方法
  7. Bean 就绪使用:Bean 可以被应用程序使用
  8. 容器关闭:当容器关闭时,调用销毁方法
  9. 销毁方法调用:按顺序调用 @PreDestroy、DisposableBean 接口方法、自定义销毁方法

理解 Bean 的生命周期有助于我们更好地控制 Spring Bean 的创建和销毁过程,正确地初始化资源和释放资源

博客内容均系原创,未经允许严禁转载!
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇