Spring Bean 生命周期详解

Spring Bean 生命周期详解

在 Spring 框架中,Bean 的生命周期由 Spring 容器全权管理。了解和掌握 Bean 的生命周期对于使用 Spring 开发稳定且高效的应用程序至关重要。本文将详细介绍 Spring Bean 生命周期的五个主要阶段:实例化、属性注入、初始化、使用和销毁,并涵盖各个阶段的关键步骤和扩展点。

1. 实例化(Instantiation)

实例化阶段包括以下关键步骤:

  • BeanNameAware 接口:如果 Bean 实现了 BeanNameAware 接口,Spring 将调用其 setBeanName 方法,将 Bean 的名称传递给它。
  • BeanFactoryAware 接口:如果 Bean 实现了 BeanFactoryAware 接口,Spring 将调用其 setBeanFactory 方法,将 BeanFactory 实例传递给它。

这些步骤确保 Bean 具有必要的上下文信息,可以与 Spring 容器进行交互。

@Override
public void setBeanName(String beanName) {
    System.out.println("BeanNameAware: setBeanName called with name " + beanName);
}

@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    System.out.println("BeanFactoryAware: setBeanFactory called");
}

2. 属性注入(Property Injection)

在实例化之后,Spring 容器会根据配置文件或注解,将配置的属性值或依赖对象注入到 Bean 实例中。这一阶段包括以下关键步骤:

  • 属性设置:Spring 容器根据配置文件或注解,将配置的属性值注入到 Bean 实例中。
  • 依赖注入:Spring 容器根据配置文件或注解,将依赖对象注入到 Bean 实例中。
public class MyBean {

    private String name;

    public void setName(String name) {
        this.name = name;
    }
}

3. 初始化(Initialization)

初始化阶段是 Bean 生命周期中最复杂的阶段,它包括属性设置、依赖注入和初始化方法的调用。该阶段包括以下关键步骤:

  • BeanPostProcessor 的 postProcessBeforeInitialization 方法:Spring 调用所有注册的 BeanPostProcessor 实现的 postProcessBeforeInitialization 方法,以便在 Bean 初始化前对其进行处理。
  • InitializingBean 接口和自定义初始化方法:如果 Bean 实现了 InitializingBean 接口,Spring 将调用其 afterPropertiesSet 方法。此外,如果配置了自定义的初始化方法,Spring 也会调用该方法。
  • @PostConstruct 注解:如果 Bean 的某个方法使用了 @PostConstruct 注解,Spring 容器将在依赖注入完成后调用该方法。@PostConstruct 注解用于标注在依赖注入完成后需要执行的初始化方法,比实现 InitializingBean 接口更加灵活和通用。
  • BeanPostProcessor 的 postProcessAfterInitialization 方法:Spring 调用所有注册的 BeanPostProcessor 实现的 postProcessAfterInitialization 方法,以便在 Bean 初始化后对其进行处理。
import javax.annotation.PostConstruct;

public class MyBean {

    private String name;

    public void setName(String name) {
        this.name = name;
    }

    @PostConstruct
    public void init() {
        System.out.println("PostConstruct: init method called");
        this.name = "Initialized Bean";
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean: afterPropertiesSet called");
    }

    public void customInit() {
        System.out.println("Custom init-method: customInit called");
    }
}

4. 使用(Ready to Use)

在完成初始化后,Bean 进入使用阶段。在这个阶段,Bean 处于完全初始化状态,可以被应用程序使用。这个阶段没有特定的扩展点,但这是应用程序逻辑使用和操作 Bean 的主要时间段。

public static void main(String[] args) {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
    MyBean myBean = context.getBean(MyBean.class);
    System.out.println("Using MyBean: " + myBean);
    context.close();
}

5. 销毁(Destruction)

当 Spring 容器关闭时,Bean 进入销毁阶段。这个阶段包括以下关键步骤:

  • DisposableBean 接口和自定义销毁方法:如果 Bean 实现了 DisposableBean 接口,Spring 将调用其 destroy 方法。此外,如果配置了自定义的销毁方法,Spring 也会调用该方法。

这些步骤确保在销毁 Bean 之前执行必要的清理操作,释放资源。

@Override
public void destroy() throws Exception {
    System.out.println("DisposableBean: destroy called");
}

public void customDestroy() {
    System.out.println("Custom destroy-method: customDestroy called");
}

完整示例

为了更好地理解这些阶段,我们提供一个完整的示例,包括 Bean 类、BeanPostProcessor 和 Spring 配置。

Bean 类

package com.example.lifecycle;

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

public class MyBean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {

    private String name;

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void setBeanName(String beanName) {
        System.out.println("BeanNameAware: setBeanName called with name " + beanName);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("BeanFactoryAware: setBeanFactory called");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("ApplicationContextAware: setApplicationContext called");
    }

    @PostConstruct
    public void init() {
        System.out.println("PostConstruct: init method called");
        this.name = "Initialized Bean";
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean: afterPropertiesSet called");
    }

    public void customInit() {
        System.out.println("Custom init-method: customInit called");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("DisposableBean: destroy called");
    }

    public void customDestroy() {
        System.out.println("Custom destroy-method: customDestroy called");
    }
}

BeanPostProcessor

package com.example.lifecycle;

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

public class CustomBeanPostProcessor implements BeanPostProcessor {

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

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("BeanPostProcessor: postProcessAfterInitialization called for " + beanName);
        return bean;
    }
}

Spring 配置

package com.example.lifecycle;

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 myBean = new MyBean();
        myBean.setName("Test Bean");
        return myBean;
    }

    @Bean
    public CustomBeanPostProcessor customBeanPostProcessor() {
        return new CustomBeanPostProcessor();
    }
}

测试 Spring 配置

package com.example.lifecycle;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringLifecycleDemo {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        
        MyBean myBean = context.getBean(MyBean.class);
        System.out.println("Using MyBean: " + myBean);

        context.close();
    }
}

参考链接

  1. Spring Framework Documentation
  2. TutorialsPoint: Spring Bean Life Cycle

在这里插入图片描述

  • 32
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黑风风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值