器 | Spring Bean 生命周期(一)

本文详细介绍了Spring Bean的生命周期,包括初始化过程(构造、依赖注入、Aware接口、BeanPostProcessor、@PostConstruct、init-method)和销毁过程(@PreDestroy、DisposableBean、destroy-method)。文中通过代码示例展示了如何在Bean类中实现InitializingBean、DisposableBean接口,以及使用@PostConstruct、@PreDestroy注解,并利用BeanPostProcessor自定义处理。文章强调了使用init-method和destroy-method属性优于直接实现接口,同时提到了从Spring 2.5开始可以使用注解介入Bean生命周期。

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

本篇文章介绍spring bean 生命周期的各个阶段,包括初始化、和销毁过程。

一、bean 的生命周期

当Spring容器启动时,通过不同的方式实例化完成bean以后,bean将放入容器中进行管理。放入到容器的bean需要执行一系列初始化后,才能使其进行可用的状态。之后,当我们不再需要bean时,bean将会被从容器中移除。

SpringBeanFactory在bean的全生命周期过程中参与管理,起到至关重要的作用。

1.1 启动初始化过程

在容器启动后,SpringBeanFactory就会开始工作。在整个初始化的过程中,严格意义上来讲,实际上会有三个层级的初始化处理,包括工厂级别的处理(BeanFactoryPostProcessor等)、容器级别的处理(InstantiationAwareBeanPostProcessorBeanPostProcessor等)、Bean级别的处理(专属某一个bean)。

工厂级别的处理,还有容器级别的处理基本上是Spring框架层面的内容,不做太深入的研究,在代码中引入这些处理,会加深代码对Spring的耦合。不过这篇文章会简单说一下可能会使用到的BeanPostProcessor

image.png

图上是bean的初始化过程,除开BeanPostProcessor后置处理器,其它的过程都是Bean级别的初始化处理。

  • 初始化开始是java本身的实例化构造对象
  • 接着set依赖注入(SDI)
  • 再接着通过*Aware接口让bean感知Spring容器资源,比如beanName,ApplicationContext
  • 然后是容器级别的BeanPostProcessor##PostProcessorBeforeInitializationbean初始化前置操作
  • 接着是执行有注解@PostConstruct的方法
  • 然后是执行接口InitializationBean#AfterPropertiesSet的实现
  • 其次是执行@Bean#initMethod
  • 最后是容器级别的BeanPostProcessor##PostProcessorBeforeInitializationbean初始化后置操作,至此bean初始化完成
1.2 容器关闭销毁过程

容器执行shutdown关闭操作后,bean就会开始一系列的销毁操作,相比较初始化操作,销毁步骤少了很多。

image.png

  • bean销毁开始执行有注解@Predestory的方法
  • 然后是执行接口DisposeBean#destory的实现
  • 最后执行@Bean#destroyMethod,至此,销毁完成

二、代码示例

下面通过简单的打印示例演示Spring bean的生命周期。

首先创建一个业务bean类,实现接口InitializingBean, DisposableBean, ApplicationContextAware, BeanNameAware

``` public class TestBean implements InitializingBean, DisposableBean, ApplicationContextAware, BeanNameAware {

private String name;

public TestBean(String name) {
    System.out.println("-------------construct--------------");
    this.name = name;
}

public void setName(String name) {
    System.out.println("-------------set method--------------");
    this.name = name;
}

public String getName() {
    return name;
}

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

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

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    System.out.println("---------BeanNameAware#setApplicationContext----");
}


@Override
public void setBeanName(String s) {
    System.out.println("----------ApplicationContextAware#setBeanName----");
}

public void initFromBean(){
    System.out.println("----------initFrom@Bean----------");
}

public void destroyFromBean(){
    System.out.println("----------destroyFrom@Bean---------------");
}

@PostConstruct
public void customInit()
{
    System.out.println("---------@PostConstruct----------");
}

@PreDestroy
public void customDestroy()
{
    System.out.println("---------@PreDestroy--------");
}

} ```

然后实现自定义的BeanPostProcessor

``` public class TestBeanProcessor implements BeanPostProcessor {

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    if(bean instanceof TestBean){
        System.out.println("------------BeanPostProcessor#postProcessAfterInitialization :" + beanName);
    }
    return bean;
}

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    if(bean instanceof TestBean){
        System.out.println("------------BeanPostProcessor#postProcessBeforeInitialization :" + beanName);
    }
    return bean;
}

} ```

最后实现一个Spring启动类

``` @SpringBootApplication @Import({ TestBeanProcessor.class }) public class SpringsApplication {

public static void main(String[] args) {
    final ConfigurableApplicationContext ctx = SpringApplication.run(SpringsApplication.class, args);
    ctx.close();
}

@ConditionalOnMissingBean
@Bean(initMethod = "initFromBean",destroyMethod = "destroyFromBean")
public TestBean testBean(){
    return new TestBean("testBean"){{
        setName("testName");
    }};
}

} ```

启动应用程序,打印结果如下

启动初始化过程

微信截图_20210413092628.png

关闭容器销毁过程

微信截图_20210413092635.png

三、总结

InitializingBeanDisposableBean不是初始化 和销毁bean 的首选方法,因为它将 bean 类与 spring 容器紧密耦合。更好的方法是在bean 定义中使用init-method,destroyMethod属性。

从 Spring 2.5开始,还可以使用注释来指定使用@postconstruct@predestroy 介入bean生命周期。

预告下一篇将会讲到BeanPostProcessor,以及*Aware

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值