spring bean 销毁的 N 种方式 (•̀ᴗ• )

x33g5p2x  于2022-06-10 转载在 Spring  
字(3.0k)|赞(0)|评价(0)|浏览(360)

嘻嘻 /ᐠ。ꞈ。ᐟ\

博主开篇打个广告哈~

博主在 哔哩哔哩 有陆续录制了一些教学视频,有兴趣的小伙伴可以去瞅瞅,求三连~

UP主 肖-信https://space.bilibili.com/384638478

正文

常用方式

@PreDestroy
  1. @PreDestroy
  2. private void preDestory() {
  3. System.out.println("销毁啦!!德玛西亚");
  4. }
实现 DisposableBean接口

实现 DisposableBean接口 重写 destroy方法

  1. @Service
  2. public class XianJian implements DisposableBean {
  3. @PreDestroy
  4. private void preDestory() {
  5. System.out.println("销毁啦!!德玛西亚 preDestory");
  6. }
  7. @Override
  8. public void destroy() throws Exception {
  9. System.out.println("销毁啦!!德玛西亚 destroy");
  10. }
  11. }

另辟蹊径

destroyMethod

定义 Bean 指定 destoryMethod

  1. @Bean(destroyMethod = "beanDestroyMethod")
  2. public XianJian xianJian() {
  3. return new XianJian();
  4. }
  1. public class XianJian implements DisposableBean {
  2. @PreDestroy
  3. private void preDestory() {
  4. System.out.println("销毁啦!!德玛西亚 preDestory");
  5. }
  6. @Override
  7. public void destroy() throws Exception {
  8. System.out.println("销毁啦!!德玛西亚 destroy");
  9. }
  10. public void beanDestroyMethod(){
  11. System.out.println("销毁啦!!德玛西亚 beanDestroyMethod");
  12. }
  13. }
AutoCloseable

实现 AutoCloseable 接口 重写 close接口

  1. @Component
  2. public class XianJian implements AutoCloseable{
  3. public void close() {
  4. System.out.println("销毁啦!!德玛西亚 close ");
  5. }
  6. }
修改BeanDifinition

这种方式用的最少…
将 beanDefinition 的 destroyMethodName 设置为 (inferred)

  1. @Component
  2. public class XxxProcessor implements MergedBeanDefinitionPostProcessor {
  3. @Override
  4. public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
  5. if(beanName.equals("xianJian")){
  6. beanDefinition.setDestroyMethodName("(inferred)");
  7. }
  8. }
  9. @Override
  10. public void resetBeanDefinition(String beanName) {
  11. MergedBeanDefinitionPostProcessor.super.resetBeanDefinition(beanName);
  12. }
  13. }

然后编写 close 或者 shutdown 方法,若都编写则 close 方法生效。

  1. @Component
  2. public class XianJian {
  3. public void close() {
  4. System.out.println("销毁啦!!德玛西亚 close ");
  5. }
  6. public void shutdown() {
  7. System.out.println("销毁啦!!德玛西亚 shutdown ");
  8. }
  9. }

最后两种骚操作 源码如下,小伙伴们可以琢磨琢磨~
org.springframework.beans.factory.support.DisposableBeanAdapter#inferDestroyMethodIfNecessary

  1. private static String inferDestroyMethodIfNecessary(Object bean, RootBeanDefinition beanDefinition) {
  2. String destroyMethodName = beanDefinition.resolvedDestroyMethodName;
  3. if (destroyMethodName == null) {
  4. destroyMethodName = beanDefinition.getDestroyMethodName();
  5. boolean autoCloseable = (bean instanceof AutoCloseable);
  6. if (AbstractBeanDefinition.INFER_METHOD.equals(destroyMethodName) ||
  7. (destroyMethodName == null && autoCloseable)) {
  8. // Only perform destroy method inference in case of the bean
  9. // not explicitly implementing the DisposableBean interface
  10. destroyMethodName = null;
  11. if (!(bean instanceof DisposableBean)) {
  12. if (autoCloseable) {
  13. destroyMethodName = CLOSE_METHOD_NAME;
  14. }
  15. else {
  16. try {
  17. destroyMethodName = bean.getClass().getMethod(CLOSE_METHOD_NAME).getName();
  18. }
  19. catch (NoSuchMethodException ex) {
  20. try {
  21. destroyMethodName = bean.getClass().getMethod(SHUTDOWN_METHOD_NAME).getName();
  22. }
  23. catch (NoSuchMethodException ex2) {
  24. // no candidate destroy method found
  25. }
  26. }
  27. }
  28. }
  29. }
  30. beanDefinition.resolvedDestroyMethodName = (destroyMethodName != null ? destroyMethodName : "");
  31. }
  32. return (StringUtils.hasLength(destroyMethodName) ? destroyMethodName : null);
  33. }

感谢笔芯ꔛꕤ

相关文章