手写简易 Spring(三)

文章目录

  • 三. 手写简易 Spring(三)
    • 1. Bean 对象初始化和销毁方法
      • 1. XML 添加 init-method 与实现 InitializingBean 接口注册初始化
      • 2. XML 添加 destroy-method 与实现 DisposableBean 接口注册销毁
      • 3. DefaultSingletonBeanRegistry 优秀的解耦方法
    • 2. 定义标记类型 Aware 接口,实现感知容器对象
      • 1. 定义
      • 2. ApplicationContextAwareProcessor 包装处理器
    • 3. Bean 对象作用域
      • 1. 定义
    • 4. 扩展其他框架 FactoryBean
      • 1. 定义
      • 2. FactoryBeanRegistrySupport 处理 FactoryBean 注册管理
    • 5. 我的代码结构
      • 1. 整体设计结构
      • 2. 我的调用类图(模拟 Spring 源码)
      • 3. 我的代码结构(模拟 Spring 源码)

三. 手写简易 Spring(三)

1. Bean 对象初始化和销毁方法

1. XML 添加 init-method 与实现 InitializingBean 接口注册初始化

  • 核心实现类 XmlBeanDefinitionReader:添加解析 XML 的 init-method 的参数放入 BeanDefinition 对象
  • 核心抽象类 AbstractAutowireCapableBeanFactory:在调用 invokeInitMethod 方法初始化时先判断是否有 InitializingBean 初始化,再判断是否有 init-method 初始化,同时避免调用两次相同方法

2. XML 添加 destroy-method 与实现 DisposableBean 接口注册销毁

  • 核心实现类 XmlBeanDefinitionReader:添加解析 XML 的 destroy-method 的参数放入 BeanDefinition 对象
  • DisposableBeanAdapter 类使用了适配器的设计模式,将俩销毁方法整合在一起
    • 先判断是否有 DisposableBean 销毁,再判断是否有 destroy-method 初销毁,同时避免调用两次相同方法
  • 核心抽象类 AbstractAutowireCapableBeanFactory:在初始化后调用 registerDisposableBeanIfNecessary 方法
    • 方法调用 DefaultSingletonBeanRegistry 类、注册带销毁的 BeanDefinition 对象
    • 存在 DisposableBean 或 destroy-method 就是带销毁的 BeanDefinition 对象
  • 解析 XML 与预加载单例对象后,手动注册销毁钩子时,调用 DefaultSingletonBeanRegistry 类的 destroySingletons 方法
    • DefaultSingletonBeanRegistry 类存在所有销毁的 BeanDefinition 集合,依次删除、同时调用 DisposableBeanAdapter 类整合的 destroy 方法

3. DefaultSingletonBeanRegistry 优秀的解耦方法

  • ConfigurableBeanFactory 接口定义了 destroySingletons 方法
  • AbstractBeanFactory 实现了 ConfigurableBeanFactory 接口但自己极其子类并未实现此方法
  • AbstractBeanFactory 交给了父类 DefaultSingletonBeanRegistry 实现 destroySingletons 方法,DefaultSingletonBeanRegistry 并没有实现 ConfigurableBeanFactory 接口因此无需 @Override
  • 核心就是 A 继承 B实现 C 时,C 的接口方法由 A 继承的父类 B 实现

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IEh9XJkH-1682183583455)(:/810c4cb567e54a61910bfc5b38f84490)]

2. 定义标记类型 Aware 接口,实现感知容器对象

1. 定义

  • 允许 Bean 对象拿到 Spring 框架中的 BeanFactory、BeanClassLoader、BeanName、ApplicationContext 等
  • 我们可以定义 Aware 标记接口,通过 instanceof 判断
    • JDK 常用标记接口:Cloneable、Serializable、RandomAccess、Remote
  • 当前继承 Aware 的接口包括:BeanFactoryAware、BeanClassLoaderAware、BeanNameAware 和 ApplicationContextAware,获取对应对象
    • 前三者属于 BeanFactory,因此在 beans.factory 包下
    • ApplicationContextAware 属于 ApplicationContext,因此在 context 包下
    • ApplicationContext 需要像容器中注册 addBeanPostProcessor ,再由 createBean 调用 applyBeanPostProcessorsBeforeInitialization 时进行操作

2. ApplicationContextAwareProcessor 包装处理器

  • ApplicationContextAwareProcessor 实现 BeanPostProcessor 接口
    • 在 refresh() 方法操作时,把 ApplicationContext 注册到 BeanPostProcessor 容器
    • 在 createBean() 方法进行 BeanPostProcessor Before 处理时调用

3. Bean 对象作用域

1. 定义

  • 是否单例存放在 BeanDefinition 中,通过 ConfigurableBeanFactory 成员变量 SCOPE_SINGLETON、SCOPE_PROTOTYPE 来定义
  • 单例与否区别
    • DefaultListableBeanFactory#preInstantiateSingletons 是否进行预初始化
    • AbstractAutowireCapableBeanFactory#createBean 创建完成对象后是否放入到内存中
    • 是否注册 Disposable 销毁方法
  • 某个 Bean 对象是否单例,可通过 XmlBeanDefinitionReader 解析 XML 文件校验

4. 扩展其他框架 FactoryBean

1. 定义

  • MyBatis 就是实现了一个 MapperFactoryBean 类,交给 Spring 管理
  • createBean 执行对象实例化、属性填充、依赖加载、前置后置处理、初始化等操作后,就执行 FactoryBean 具体对象中的 getObject 对象

2. FactoryBeanRegistrySupport 处理 FactoryBean 注册管理

  • AbstractBeanFactory 抽象类继承 DefaultSingletonBeanRegistry 实现类,中间加一层 FactoryBeanRegistrySupport 抽象类
    • 它处理关于 FactoryBean 对象的注册管理
  • FactoryBeanRegistrySupport 不实现 FactoryBean 接口,仅是依赖它

5. 我的代码结构

1. 整体设计结构

2. 我的调用类图(模拟 Spring 源码)

3. 我的代码结构(模拟 Spring 源码)


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/14297.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JavaSE-06 [面向对象OOP + 封装]

JavaSE-06 [面向对象OOP 封装] 第一章 面向对象思想 1.1 面向过程和面向对象 面向过程: 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了面向对象: 面向对象是…

MITA触摸屏维修WP4053米塔工控机控制屏维修

MITA-TEKNIK米塔触摸屏维修工控机工控屏控制器维修DISPLAY 2COM全系列型号 Mita-Teknik触摸屏维修常见故障:上电无显示,运行报故障,无法与电脑通讯,触摸无反应,触控板破裂,触摸玻璃,上电黑屏&a…

云原生|kubernetes|rancher-2.6.4安装部署简明手册

前言: rancher是一个比较特殊的开源的kubernetes管理工具,特殊在它是一个名称为k3s的简单kubernetes集群,而该集群是在kubernetes集群内的。 OK,本文将讲述如何在centos7服务器上,在已有的kubernetes-1.23.15集群内,…

springboot,Flowable 流程实例的激活与挂起(二)

一.简介 接上一篇 springboot&#xff0c;Flowable 流程实例的激活与挂起&#xff08;一&#xff09; 二.流程实例的挂起与激活 1.流程实例的挂起 挂起一个流程实例的代码如下&#xff1a; Test void test08() {List<ProcessDefinition> list repositoryService.cr…

Git相关使用

私人博客 许小墨のBlog —— 菜鸡博客直通车 系列文章完整版&#xff0c;配图更多&#xff0c;CSDN博文图片需要手动上传&#xff0c;因此文章配图较少&#xff0c;看不懂的可以去菜鸡博客参考一下配图&#xff01; 系列文章目录 前端系列文章——传送门 后端系列文章——传送…

数组模拟实现单链表快速操作

前言&#xff1a;我们都知道链表的一般模式是由结构体加指针来实现的&#xff0c;但是在实际的比赛中&#xff0c;结构体指针来实现链表的操作并不常用&#xff0c;原因是因为我们在增加节点时需要开辟新的内存&#xff0c;而比赛时给出的样例大多都是十几万个数据&#xff0c;…

找出1-1000中的所有完美数

再次练习查找完美数&#xff0c;找出 1-1000 中的所有完美数。 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《 python 完全自学教程》&#xff0c;不仅仅是基础那么简单…… 地址&#xff1a;https://l…

Git的安装和学习使用(一)

本篇文章旨在分享本人在学习Git时的随笔记&#x1f929; 文章目录 一、Git 快速入门1.1 Git 概述1.2 SCM概述1.3 Git 安装1.3.1 软件下载1.3.2 软件安装1.3.3 软件测试 二、Git 基础使用2.1 Git 概念2.1.1 版本控制2.1.2 分布式2.1.3 系统2.1.4 区域 2.2 Git 基础指令2.2.1 Lin…

任务调度原理 通俗讲解详细(FreeRTOS)

寄存器说明 以cortex-M3&#xff0c;首先先要了解比较特别的几个寄存器&#xff1a; r15 PC程序计数器&#xff08;Program Counter&#xff09;,存储下一条要执行的指令的地址。 r14 LR连接寄存器&#xff08;Link Register &#xff09;&#xff0c;保存函数返回地址&#x…

Rancher 部署 Elasticsearch 8.5.1 版本服务

前言 从 es7 升级到 es8 之后&#xff0c;启动容器默认启用了 ssl 安全传输配置&#xff0c;但是在 Rancher 中部署的话&#xff0c;需要挂载 pvc 实现 data、logs 等目录持久化&#xff0c;启用 ssl 需要对证书等进行操作&#xff0c;非常麻烦&#xff0c;非常坑。 本文以启…

bitset(位图)的使用与模拟实现

bitset&#xff08;位图&#xff09; 位图引入bitset的使用bitset&#xff08;位图&#xff09;的模拟实现bitset类各函数接口总览bitset类的实现构造函数set、reset、flip、testsize、countany、none、all打印函数 位图引入 问&#xff1a;给40亿个不重复的无符号整数&#xf…

AlgoC++第三课:C++世界观

目录 C世界观前言1. 程序逻辑2. 内存的逻辑3. 调度的逻辑4. 编译的逻辑5. 作用域的逻辑6. 命名空间的逻辑7. 生命周期的逻辑8. C类的逻辑9. 编译时和运行时的逻辑总结 C世界观 前言 手写AI推出的全新面向AI算法的C课程 Algo C&#xff0c;链接。记录下个人学习笔记&#xff0c…

Vue+Vant封装通用模态框单选框组件

前言 我们知道&#xff0c;在vant组件中提供的组件往往是比较基础的&#xff0c;能够满足基本需求。但是我们想实现ui设计的一些比较丰富效果的组件&#xff0c;需要自己去实现&#xff0c;且当项目中多次用到的时候&#xff0c;我们将以组件化的思想将其封装起来&#xff0c;…

Linux服务器出现503 服务不可用错误怎么办?

​  HTTP 503 服务不可用错误代码表示网站暂时不可用。无论您是网站访问者还是管理员&#xff0c;503 页面都很麻烦。尽管该错误表明存在服务器端问题&#xff0c;但对于访问者和网络管理员来说&#xff0c;有一些可能的解决方案。本文将解释Linux服务器出现503 服务不可用错…

scratch足球射门练习 中国电子学会图形化编程 少儿编程 scratch编程等级考试一级真题和答案解析2023年3月

目录 scratch足球射门练习 一、题目要求 1、准备工作 2、功能实现 二、案例分析

【网络安全】红队基础免杀

引言 本文主要介绍“反射型 dll 注入”及“柔性加载”技术。 反射型 dll 注入 为什么需要反射型 dll 注入 常规的 dll 注入代码如下&#xff1a; int main(int argc, char *argv[]) {HANDLE processHandle;PVOID remoteBuffer;wchar_t dllPath[] TEXT("C:\\experime…

分享几个国内免费的ChatGPT镜像网址(亲测有效-4月25日更新)

最近由于ChatGPT的爆火也让很多小伙伴想去感受一下ChatGPT的魅力&#xff0c;那么今天就分享几个ChatGPT国内的镜像网址&#xff0c;大家可以直接使用&#xff01;记得点赞收藏一下呦&#xff01; 1、AQ Bot&#xff0c;网址&#xff1a;点我 https://su.askaiw.com/aq 缺点&…

面试篇:Redis

一、缓存穿透 1、缓存穿透 查询一个不存在的数据&#xff0c;mysql查询不到数据也不会直接写入缓存&#xff0c;就会导致每次请求都查数据库。即&#xff1a;大量请求根本不存在的key 2、查询流程 3、出现原因 业务层误将缓存和库中的数据删除了&#xff0c;也可能是有人恶…

JUC-多线程(12. AQS-周阳)学习笔记

文章目录 1. 可重入锁1.1. 概述1.2. 可重入锁类型1.3. Synchronized 可重入实现机理 2. LockSupport2.1. LockSupport 是什么2.2. 3种线程等待唤醒的方法2.2.1 Object 的等待与唤醒2.2.2. Condition接口中的等待与唤醒2.2.3. 传统的 synchronized 和 Lock 实现等待唤醒通知的约…

【手把手做ROS2机器人系统开发一】开发环境搭建

【手把手做ROS2机器人系统开发一】开发环境搭建 目录 【手把手做ROS2机器人系统开发一】开发环境搭建 一、专栏介绍&#xff1a; 二、开发环境搭建&#xff1a; 1.Ubuntu系统安装 2.ROS2系统环境安装 3.测试系统运行 一、专栏介绍&#xff1a; 大家好&#xff0c;今天给大家…
最新文章