前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Spring Ben的生命周期95%的人都不知道这几个点

Spring Ben的生命周期95%的人都不知道这几个点

作者头像
lyb-geek
发布2025-02-10 16:03:21
发布2025-02-10 16:03:21
4200
代码可运行
举报
文章被收录于专栏:Linyb极客之路Linyb极客之路
运行总次数:0
代码可运行

1. 简介

Spring管理Bean的声明周期可以实现 InitializingBeanDisposableBean 接口。容器会调用前者的 afterPropertiesSet() 和后者的 destroy() 来让 Bean 在初始化和销毁 Bean 时执行某些操作。本篇文章将只介绍Bean的销毁

回顾Bean销毁

实现接口DisposableBean

代码语言:javascript
代码运行次数:0
复制
@Component
public class BeanLifecycle03 implements DisposableBean {

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

当容器销毁时会调用上面的destroy方法。

通过注解@PreDestroy

代码语言:javascript
代码运行次数:0
复制
@PreDestroy
public void destroyProcess() {
  System.out.println("des...") ;
}

注:这里的方法名可以随意,同时修饰符也可以是private

同时应用上面2种方式:@PreDestroy优先于Disposablebean执行。

通过注解@Bean配置

代码语言:javascript
代码运行次数:0
复制
// 定义bean
public class BeanLifecycle04 {
  
  public void customDestroy() {
    System.out.println("BeanLifecycle04 customDestroy...") ;
  }
}
@Bean(destroyMethod = "customDestroy")
BeanLifecycle04 beanLifecycle04() {
  return new BeanLifecycle04() ;
}

通过destroyMethod属性指定销毁的回调方法。

接下来将介绍销毁回调的其它应用方式。

2. 高级技能

2.1 @Bean自动应用销毁回调

在通过@Bean定义对象时,该注解有个destroyMethod属性默认值是: (inferred)

如果你不去修改该属性,那么你可以在你定义的bean对象中定义如下2个名称的方法

  • close
  • shutdown

如果你的方法中有上面2个方法任意一个,那么容器在关闭时也是会调用对应的回调方法的,close优先于shutdown方法。如下示例:

代码语言:javascript
代码运行次数:0
复制
public class CommonService {
  public void close() {
    System.out.println("CommonService close...") ;
  }
  public void shutdown() {
    System.out.println("CommonService shutdown...") ;
  }
}
@Bean
public CommonService commonService() {
  return new CommonService() ;
}

如上定义后,容器销毁时自动调用上面的close方法,如果没有close方法则查找shutdown方法。这是Spring的自动推断机制

2.2 实现AutoCloseable接口

除了上面的方式外,我们还可以让对象实现AutoCloseable接口来执行销毁回调。

代码语言:javascript
代码运行次数:0
复制
public class BeanLifecycle04 implements AutoCloseable {
  @Override
  public void close() throws Exception {
    System.out.println("BeanLifecycle04 AutoCloseable close...") ;
  }
}
@Bean
public BeanLifecycle04 beanLifecycle04() {
  return new BeanLifecycle04() ;
}

这种方式也是会自动执行close回调方法。

这种方式还有一个好处是,我们可以直接在类上添加@Component注解,这种方式也可以自动调用close方法。

2.3 方法参数

在特殊的情况(通过配置销毁方法)销毁方法都能接收一个参数,而且参数类型必须是Boolean类型,如下示例:

代码语言:javascript
代码运行次数:0
复制
public class CommonService {
  public void close(boolean flag) {
    System.out.printf("CommonService close...flag: %s%n", flag) ;
  }
}
@Bean(destroyMethod = "close")
public CommonService commonService() {
  return new CommonService() ;
}

通过上面的方式你可以接受一个boolean类型的参数,必须是boolean,如果是其它参数将会报异常。注:自动推断机制不支持,反而有了参数后将不会执行

2.4 统一添加推断机制

如果你想对所有的bean或者是某些bean统一配置可进行自动推断机制那么你可以通过如下的方式进行处理

代码语言:javascript
代码运行次数:0
复制
public class ProcessInferredBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor {

  @Override
  public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    String[] names = registry.getBeanDefinitionNames() ;
    for (String name : names) {
      BeanDefinition beanDefinition = registry.getBeanDefinition(name) ;
      String className = beanDefinition.getBeanClassName() ;
      if (Objects.nonNull(className) && className.startsWith("com.pack")) {
        // 名称必须是它
        beanDefinition.setDestroyMethodName("(inferred)") ;
      }
    }
  }
}

如上这样配置后,只要你的bean对象中存在上面说的方法名,那么容器在关闭时就会调用对应的销毁回调方法。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-02-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Linyb极客之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档