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

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 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依赖注入相关源码



目录
相关文章
|
2月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
86 2
|
8天前
|
存储 设计模式 算法
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。 行为型模式分为: • 模板方法模式 • 策略模式 • 命令模式 • 职责链模式 • 状态模式 • 观察者模式 • 中介者模式 • 迭代器模式 • 访问者模式 • 备忘录模式 • 解释器模式
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
|
8天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: • 代理模式 • 适配器模式 • 装饰者模式 • 桥接模式 • 外观模式 • 组合模式 • 享元模式
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
8天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是"将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。创建型模式分为5种:单例模式、工厂方法模式抽象工厂式、原型模式、建造者模式。
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
2月前
|
缓存 监控 Java
Java线程池提交任务流程底层源码与源码解析
【11月更文挑战第30天】嘿,各位技术爱好者们,今天咱们来聊聊Java线程池提交任务的底层源码与源码解析。作为一个资深的Java开发者,我相信你一定对线程池并不陌生。线程池作为并发编程中的一大利器,其重要性不言而喻。今天,我将以对话的方式,带你一步步深入线程池的奥秘,从概述到功能点,再到背景和业务点,最后到底层原理和示例,让你对线程池有一个全新的认识。
56 12
|
27天前
|
PyTorch Shell API
Ascend Extension for PyTorch的源码解析
本文介绍了Ascend对PyTorch代码的适配过程,包括源码下载、编译步骤及常见问题,详细解析了torch-npu编译后的文件结构和三种实现昇腾NPU算子调用的方式:通过torch的register方式、定义算子方式和API重定向映射方式。这对于开发者理解和使用Ascend平台上的PyTorch具有重要指导意义。
|
8天前
|
安全 搜索推荐 数据挖掘
陪玩系统源码开发流程解析,成品陪玩系统源码的优点
我们自主开发的多客陪玩系统源码,整合了市面上主流陪玩APP功能,支持二次开发。该系统适用于线上游戏陪玩、语音视频聊天、心理咨询等场景,提供用户注册管理、陪玩者资料库、预约匹配、实时通讯、支付结算、安全隐私保护、客户服务及数据分析等功能,打造综合性社交平台。随着互联网技术发展,陪玩系统正成为游戏爱好者的新宠,改变游戏体验并带来新的商业模式。
|
3月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
249 2
|
7天前
|
Java 数据库连接 Maven
最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)
自动装配是现在面试中常考的一道面试题。本文基于最新的 SpringBoot 3.3.3 版本的源码来分析自动装配的原理,并在文未说明了SpringBoot2和SpringBoot3的自动装配源码中区别,以及面试回答的拿分核心话术。
最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)
|
14天前
|
NoSQL Java Redis
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
63 14

推荐镜像

更多