Spring之Bean的生命周期源码解析(三 Bean的创建与销毁)

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: Spring之Bean的生命周期源码解析(三 Bean的创建与销毁)

一、前言

这是我Spring专栏的第八篇文章: Spring之Bean生命周期源码分析(二), 主要讲解了获取Bean的销毁, 也是Bean生命周期内的最后一步. 在看本篇文章之前建议先看一下上篇文章当做前置学习 Spring之Bean生命周期源码分析(二)

Spring专栏全部内容如下:

二、记录有销毁方法的Bean

前置信息 - 设置Bean的销毁方法

如下图所示, 我们可以在Bean方法上实现 DisposableBean接口的 destory方法, 这个方法就是 Bean销毁时所执行的方法

网络异常,图片无法展示
|

在启动类执行相应的 close方法就会对 bean对象进行销毁

网络异常,图片无法展示
|

判断当前 Bean是否存在销毁方法

Bean的销毁方法在 AbstractBeanFactory.registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd)

网络异常,图片无法展示
|

我们直接去看if判断, 有一个 requiresDestruction(bean, mbd)方法, 这个方法就是去判断你的Bean有没有销毁方法

网络异常,图片无法展示
|

DisposableBeanAdapter.hasDestroyMethod方法

首先我们进入 DisposableBeanAdapter.hasDestroyMethod方法

在这个方法里, 我用红框圈了一个判断条件, 通过方法名称就可以判断出来他是判断这个 bean的实体类上是否有bean的销毁方法的, 我们点进去看一下

网络异常,图片无法展示
|

点进去之后可以看到, 它最开始就去判断我们的 bean实体类有没有去实现接口 DisposableBean或者 AutoCloseable, 如果实现了这两个接口, 那么直接返回true, 代表着这个 bean有销毁方法

如果没有实现, 那我们接着往下面走, 可以看到它执行了一个方法 inferDestroyMethodIfNecessary, 并将其返回, 该方法详情如下图所示:

网络异常,图片无法展示
|

该方法简单讲解:

  • 通过 BeanDefinition取出指定的销毁方法名字
  • 如果没有指定
  • 在通过 BeanDefinition.getDestroyMethodName取一次
  • 如果获取到的 destroyMethodName == inferred
  • 就会去判断有没有实现 DisposableBean 接口
  • 肯定是没有实现的, 之前就已经判断过了
  • 获取当前 bean对应 类的close方法, 就把这个方法当做销毁方法
  • 如果没有找到, 就去找 shutdown方法, 把这个方法当做销毁方法
  • 最后就是两个三元运算符, 这个没什么好说的了

hasDestructionAwareBeanPostProcessors方法

这个方法就是判断当前 bean有没有销毁的逻辑

DisposableBeanAdapter.hasApplicableProcessors

调用所有的定义的销毁的 postProcessor

网络异常,图片无法展示
|

上图中的if判断有一个方法 processor.requiresDestrunction(bean) 是用来判断当前Bean的类有没有加上 @PreDestory注解, 如果有就返回 true, 就证明了, 是通过注解的方式实现了销毁方法

确定该 Bean对象有销毁方法后

确定该 Bean对象有销毁方法后就会进入下图这个判断

网络异常,图片无法展示
|

如果 BeanDefinition 对象是单例的

就会进入下面的方法

网络异常,图片无法展示
|

可以看到这个方法就是通过构造方法创建了一个 DisposableBeanAdapter实例,然后将这个实例和 beanName传进了 registerDisposableBean方法中, 我们看一下这个方法

网络异常,图片无法展示
|

可以看到, 最后就是这个beanName和创建的 DisposableBean放进了一个map中

网络异常,图片无法展示
|

如果 BeanDefinition对象不是单例的

如下图所示:

  • 如果当前 BeanDefinition不是单例的
  • 那么会取出当前 BeanDefinition的Scope类型
  • 并执行对应的 registerDestructionCallback方法

和单例一样的是, 也是传递了一个 beanName和DisposableBean类的实例

网络异常,图片无法展示
|

但是点进这个方法内部可以看到, 他的内部实现和单例的情况不一样

三、Bean的销毁

关于Bean的销毁, 我们通过容器关闭执行的 close方法点进去

网络异常,图片无法展示
|

点击去可以看到一个 doClass()方法

网络异常,图片无法展示
|

doClass方法如下图所示:

网络异常,图片无法展示
|

在这个方法里面, 也有很多知识点,我们后续会讲到, 目前主要看的方法是 destroyBeans(), 点进这个方法

网络异常,图片无法展示
|

如上图所示, 我们可以通过这个方法名称看出来, 它销毁了我们 Bean工厂内所有的单例Bean

原型Bean Spring中都没有存储, 所以不用销毁

在往下走, 我们跳转到对应的方法

网络异常,图片无法展示
|

网络异常,图片无法展示
|

super.destroySingletons();

先看它执行了它父类的方法

网络异常,图片无法展示
|

查看是否有销毁的方法

我们可以看到, 他去遍历了一个map, 这个map就是之前我们在记录销毁方法时的 map

网络异常,图片无法展示
|

在这个方法中, 可以看到还是先移除掉单例池

网络异常,图片无法展示
|

下一步执行了以下代码, 将自己从map中移除掉

disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
复制代码

最后执行了 destroyBean方法

destroyBean方法

如下图所示, 这个map表示的是, 当前bean被哪些bean依赖了, 当前bean要销毁的话, 其他的bean也要被销毁

网络异常,图片无法展示
|

这个方法比较重要的是他最后执行了 destroy方法(销毁方法)

网络异常,图片无法展示
|

清空单例池

这一步就是他去遍历所有有销毁方法, 销毁逻辑的Bean, 加入没有销毁方法的Bean, 那么就执行下面的三个clear, 清空map

网络异常,图片无法展示
|

最后执行了一个方法, 清空了单例池

网络异常,图片无法展示
|

四、总结

到这里 Bean销毁的记录和执行就结束了, 下一篇文章开始讲解Spring依赖注入相关源码



目录
相关文章
|
8天前
|
Java 对象存储 开发者
解析Spring Cloud与Netflix OSS:微服务架构中的左右手如何协同作战
Spring Cloud与Netflix OSS不仅是现代微服务架构中不可或缺的一部分,它们还通过不断的技术创新和社区贡献推动了整个行业的发展。无论是对于初创企业还是大型组织来说,掌握并合理运用这两套工具,都能极大地提升软件系统的灵活性、可扩展性以及整体性能。随着云计算和容器化技术的进一步普及,Spring Cloud与Netflix OSS将继续引领微服务技术的发展潮流。
21 0
|
19天前
|
XML Java 数据格式
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
Spring 第二节内容补充 关于Bean配置的更多内容和细节 万字详解!
116 18
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
|
6天前
|
XML Java 数据格式
spring复习02,xml配置管理bean
详细讲解了Spring框架中基于XML配置文件管理bean的各种方式,包括获取bean、依赖注入、特殊值处理、属性赋值、集合类型处理、p命名空间、bean作用域及生命周期和自动装配。
spring复习02,xml配置管理bean
|
4天前
|
缓存 Java Spring
手写Spring Ioc 循环依赖底层源码剖析
在Spring框架中,IoC(控制反转)是一个核心特性,它通过依赖注入(DI)实现了对象间的解耦。然而,在实际开发中,循环依赖是一个常见的问题。
13 4
|
9天前
|
XML 缓存 Java
spring源码剖析-spring-beans(内部核心组件,BeanDefinition的注册,BeanWapper创建)
spring源码剖析-spring-beans(内部核心组件,BeanDefinition的注册,BeanWapper创建)
38 10
|
9天前
|
XML 存储 Java
spring源码刨析-spring-beans(内部核心组件,beanDefinition加载过程)
spring源码刨析-spring-beans(内部核心组件,beanDefinition加载过程)
|
6天前
|
存储 缓存 Java
在Spring Boot中使用缓存的技术解析
通过利用Spring Boot中的缓存支持,开发者可以轻松地实现高效和可扩展的缓存策略,进而提升应用的性能和用户体验。Spring Boot的声明式缓存抽象和对多种缓存技术的支持,使得集成和使用缓存变得前所未有的简单。无论是在开发新应用还是优化现有应用,合理地使用缓存都是提高性能的有效手段。
13 1
|
6天前
|
XML Java 数据格式
spring复习03,注解配置管理bean
Spring框架中使用注解配置管理bean的方法,包括常用注解的标识组件、扫描组件、基于注解的自动装配以及使用注解后的注意事项,并提供了一个基于注解自动装配的完整示例。
spring复习03,注解配置管理bean
|
9天前
|
XML 存储 Java
Spring-源码深入分析(二)
Spring-源码深入分析(二)
|
9天前
|
XML 设计模式 Java
Spring-源码深入分析(一)
Spring-源码深入分析(一)

推荐镜像

更多
下一篇
无影云桌面