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

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



目录
相关文章
|
15天前
|
XML Java 测试技术
Spring IOC—基于注解配置和管理Bean 万字详解(通俗易懂)
Spring 第三节 IOC——基于注解配置和管理Bean 万字详解!
98 26
|
2月前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是"将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。创建型模式分为5种:单例模式、工厂方法模式抽象工厂式、原型模式、建造者模式。
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
2月前
|
存储 设计模式 算法
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。 行为型模式分为: • 模板方法模式 • 策略模式 • 命令模式 • 职责链模式 • 状态模式 • 观察者模式 • 中介者模式 • 迭代器模式 • 访问者模式 • 备忘录模式 • 解释器模式
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
|
2月前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: • 代理模式 • 适配器模式 • 装饰者模式 • 桥接模式 • 外观模式 • 组合模式 • 享元模式
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
2月前
|
存储 Java Spring
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
|
2月前
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
|
30天前
|
自然语言处理 数据处理 索引
mindspeed-llm源码解析(一)preprocess_data
mindspeed-llm是昇腾模型套件代码仓,原来叫"modelLink"。这篇文章带大家阅读一下数据处理脚本preprocess_data.py(基于1.0.0分支),数据处理是模型训练的第一步,经常会用到。
52 0
|
2月前
|
安全 搜索推荐 数据挖掘
陪玩系统源码开发流程解析,成品陪玩系统源码的优点
我们自主开发的多客陪玩系统源码,整合了市面上主流陪玩APP功能,支持二次开发。该系统适用于线上游戏陪玩、语音视频聊天、心理咨询等场景,提供用户注册管理、陪玩者资料库、预约匹配、实时通讯、支付结算、安全隐私保护、客户服务及数据分析等功能,打造综合性社交平台。随着互联网技术发展,陪玩系统正成为游戏爱好者的新宠,改变游戏体验并带来新的商业模式。
|
Java 程序员 索引
Spring的三种创建方式和各种属性的注入(二)
Spring的三种创建方式和各种属性的注入(二)
131 0
Spring的三种创建方式和各种属性的注入(二)
|
27天前
|
XML Java 应用服务中间件
Spring Boot 两种部署到服务器的方式
本文介绍了Spring Boot项目的两种部署方式:jar包和war包。Jar包方式使用内置Tomcat,只需配置JDK 1.8及以上环境,通过`nohup java -jar`命令后台运行,并开放服务器端口即可访问。War包则需将项目打包后放入外部Tomcat的webapps目录,修改启动类继承`SpringBootServletInitializer`并调整pom.xml中的打包类型为war,最后启动Tomcat访问应用。两者各有优劣,jar包更简单便捷,而war包适合传统部署场景。需要注意的是,war包部署时,内置Tomcat的端口配置不会生效。
202 17
Spring Boot 两种部署到服务器的方式

热门文章

最新文章

推荐镜像

更多