Spring DefaultListableBeanFactory源码分析
目录
一、概述
二、主要功能
三、核心功能解析
Bean定义的存储结构
ConcurrentHashMap的使用和意义
四、总结
一、概述
DefaultListableBeanFactory 是 Spring 框架中的一个核心类,它继承自AbstractAutowireCapableBeanFactory类,实现了 ListableBeanFactory 接口,并提供了一些额外的方法用于注册和获取Bean的定义。该类提供了 Spring 应用上下文中的 bean 定义和实例的管理功能。它是 Spring 容器的基础,负责管理 bean 的生命周期、依赖注入等核心功能。
二、主要功能
- Bean 定义管理:
DefaultListableBeanFactory存储了所有的 bean 定义,这些定义通常来自于 XML 配置文件、注解或其他配置方式。 - Bean 实例化:根据 bean 的定义,容器负责实例化它们。
- 依赖注入:容器负责自动装配 bean 之间的依赖关系。
- 生命周期管理:容器负责管理 bean 的生命周期,从创建到销毁。
- 事件发布:容器负责发布与 bean 相关的各种事件,如初始化、销毁等。
三、关键代码分析
- Bean 定义存储
private final Map<String, RootBeanDefinition>
beanDefinitionMap = new ConcurrentHashMap<>(256);
这里使用了一个 ConcurrentHashMap 来存储所有的 bean 定义。键是 bean 的名称,值是 RootBeanDefinition 对象,它包含了 bean 的完整定义信息。
2. Bean 实例化
当需要实例化一个 bean 时,DefaultListableBeanFactory 会使用 getBean() 方法。这个方法首先检查请求的 bean 是否已经存在实例,如果存在则直接返回;如果不存在,它会调用 createBean() 方法来创建 bean 的实例。
3. 依赖注入
在创建 bean 的实例后,DefaultListableBeanFactory 会自动检测该 bean 的所有依赖项,并注入这些依赖。这个过程通过反射实现,利用了 Java 的 Field 和 Method 类来访问和修改对象的属性。
4. 事件发布
当 bean 的生命周期发生变化时(如初始化、销毁等),DefaultListableBeanFactory 会发布相应的事件。这些事件会被注册的监听器捕获并处理。事件的发布通过 Spring 的事件机制实现,基于发布-订阅模式。
5. 其他关键方法
addBeanPostProcessor: 用于添加后处理器,可以在 bean 创建后对其进行进一步处理。registerBeanDefinition: 用于注册一个新的 bean 定义。removeBeanDefinition: 用于移除一个已注册的 bean 定义。getBeanNamesForType: 根据给定的类型获取所有相关的 bean 名称。getBeansOfType: 根据给定的类型获取所有相关的 bean 实例。getAliases: 获取指定名称的所有别名。
四、总结
DefaultListableBeanFactory 是 Spring 框架中非常重要的一个类,它提供了基础的 bean 管理功能,使得开发者能够专注于业务逻辑而不是底层的bean 管理。通过对它的源码分析,我们可以深入了解 Spring 的核心工作原理,从而更好地利用这个框架来构建企业级应用。
下面是DefaultListableBeanFactory的精简源码:
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry {// 用于保存Bean定义的Mapprivate final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();// 用于保存Bean实例的Mapprivate final Map<String, Object> singletonObjects = new ConcurrentHashMap<>();// 用于保存Bean的作用域的Mapprivate final Map<String, Scope> scopes = new ConcurrentHashMap<>();// 用于保存Bean的后置处理器的Listprivate final List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();// 用于保存Bean的初始化方法的Mapprivate final Map<String, String> initMethods = new ConcurrentHashMap<>();// 用于保存Bean的销毁方法的Mapprivate final Map<String, String> destroyMethods = new ConcurrentHashMap<>();// 用于保存Bean的销毁回调的Listprivate final List<Runnable> destroyCallbacks = new CopyOnWriteArrayList<>();// 用于保存Bean的依赖关系的Mapprivate final Map<String, Set<String>> dependentBeans = new ConcurrentHashMap<>();// 用于保存Bean的依赖关系反转的Mapprivate final Map<String, Set<String>> dependenciesForBean = new ConcurrentHashMap<>();// 用于保存Bean的别名的Mapprivate final Map<String, String> aliases = new ConcurrentHashMap<>();// 用于保存Bean的类型的Mapprivate final Map<String, Class<?>> types = new ConcurrentHashMap<>();// 用于保存Bean的标记的Listprivate final List<String> alreadyCreated = new CopyOnWriteArrayList<>();// 用于保存Bean的ClassLoaderprivate ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();// 用于保存Bean的属性编辑器的Mapprivate final Map<Class<?>, PropertyEditor> customEditors = new ConcurrentHashMap<>();// 用于保存Bean的TypeConverterprivate TypeConverter typeConverter;// ... 其他成员变量和方法省略 ...@Overridepublic void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {Assert.notNull(beanName, "Bean name must not be null");Assert.notNull(beanDefinition, "BeanDefinition must not be null");if (containsBeanDefinition(beanName)) {throw new BeanDefinitionStoreException("Bean definition for bean '" + beanName + "' already exists");}beanDefinitionMap.put(beanName, beanDefinition);if (beanDefinition instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDefinition).hasBeanClass()) {Class<?> beanClass = ((AbstractBeanDefinition) beanDefinition).getBeanClass();types.put(beanName, beanClass);}if (beanDefinition instanceof AnnotatedBeanDefinition) {MethodMetadata factoryMethodMetadata = ((AnnotatedBeanDefinition) beanDefinition).getFactoryMethodMetadata();if (factoryMethodMetadata != null && beanDefinition instanceof AbstractBeanDefinition) {((AbstractBeanDefinition) beanDefinition).setResolvedFactoryMethod(factoryMethodMetadata);}}// 发布Bean定义注册事件if (hasBeanCreationStarted()) {// 如果容器已经开始创建Bean,则立即初始化该BeanfinishBeanFactoryInitialization();}}@Overridepublic BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {Assert.notNull(beanName, "Bean name must not be null");BeanDefinition bd = beanDefinitionMap.get(beanName);if (bd == null) {throw new NoSuchBeanDefinitionException(beanName);}return bd;}@Overridepublic boolean containsBeanDefinition(String beanName) {Assert.notNull(beanName, "Bean name must not be null");return beanDefinitionMap.containsKey(beanName);}// ... 其他方法省略 ...protected void processBeanDefinition(BeanDefinition beanDefinition) throws BeanDefinitionStoreException {if (beanDefinition instanceof AbstractBeanDefinition) {AbstractBeanDefinition abstractBeanDefinition = (AbstractBeanDefinition) beanDefinition;if (abstractBeanDefinition.hasBeanClass()) {if (!abstractBeanDefinition.isSynthetic()) {validateBeanDefinition(abstractBeanDefinition);}prepareMethodOverrides(abstractBeanDefinition);}}}// ... 其他方法省略 ...@Overrideprotected void initBeanWrapper(BeanWrapper bw) {bw.setConversionService(getConversionService());}@Overrideprotected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {// 实例化BeanObject bean = resolveBeforeInstantiation(beanName, mbd);if (bean != null) {return bean;}return doCreateBean(beanName, mbd, args);}// ... 其他方法省略 ...}
以上是DefaultListableBeanFactory的源码核心部分。它主要通过使用Java的集合类来存储和管理Bean的定义、实例、作用域、后置处理器等信息。它实现了BeanDefinitionRegistry接口,可以注册和获取Bean的定义。它还继承自AbstractAutowireCapableBeanFactory类,提供了创建和初始化Bean的功能。
相关文章:
Spring DefaultListableBeanFactory源码分析
目录 一、概述 二、主要功能 三、核心功能解析 Bean定义的存储结构 ConcurrentHashMap的使用和意义 四、总结 一、概述 DefaultListableBeanFactory 是 Spring 框架中的一个核心类,它继承自AbstractAutowireCapableBeanFactory类,实现了 ListableBeanF…...
关于MySQL、分布式系统、SpringCloud面试题
前言 之前为了准备面试,收集整理了一些面试题。 本篇文章更新时间2023年12月27日。 最新的内容可以看我的原文:https://www.yuque.com/wfzx/ninzck/cbf0cxkrr6s1kniv MySQL 索引 说一下有哪些锁? 行锁有哪些? 性能优化 分库分表…...
2023年中职“网络安全”——B-5:网络安全事件响应(Server2216)
B-5:网络安全事件响应 任务环境说明: 服务器场景:Server2216(开放链接) 用户名:root密码:123456 1、黑客通过网络攻入本地服务器,通过特殊手段在系统中建立了多个异常进程,找出启…...
【论文解读】Learning based fast H.264 to H.265 transcoding
时间: 2015 年 级别: APSIPA 机构: 上海电力大学 摘要 新提出的视频编码标准HEVC (High Efficiency video coding)以其比H.264/AVC更好的编码效率,被工业界和学术界广泛接受和采用。在HEVC实现了约40%的编码效率提升的同时&…...
[vue]Echart使用手册
[vue]Echart使用手册 使用环境Echart的使用Echart所有组件和图表类型Echart 使用方法 使用环境 之前是在JQuery阶段使用Echart,直接引入Echart的js文件即可,现在是在vue中使用,不仅仅时echarts包,还需要安装vue-echarts: "…...
视频人脸识别马赛克处理
文章目录 前言一、实现思路?二、Coding三、实现效果 前言 前面几篇文章我们尝试了使用opencv完成图像人脸识别以及识别后贴图或者打马赛克的方法。 偶尔我们也会有需求在视频中将人脸马赛克化,opencv也提供了相应的方法来实现这个功能。 一、实现思路&a…...
2023-12-27 Python PC获取鼠标位置,移动鼠标到相应的位置 定时自动模拟鼠标点击,用于简单测试app用
一、核心源码如下: import pyautogui import timepyautogui.moveTo(600, 800) for i in range(20):time.sleep(0.1)x, y pyautogui.position()print("mouse position:", x, y)pyautogui.click()二、定时自动模拟鼠标点击,模拟键盘按键 impo…...
如何解决服务器CA证书过期的问题
一、问题的提出 最近在学习VPS,在Linux系统里给服务器安装某项服务时,在服务的log里看到下面的错误信息: failed to verify certificate: x509: certificate has expired or is not yet valid: current time 2023-12-25T04:42:38-05:00 is a…...
计算机基础面试题总结
47、OSI、TCP/IP、五层协议的体系结构以及各层协议 OSI分层(7层):物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。 TCP/IP分层(4层):网络接口层、网际层、运输层、应用层。 五层协议&…...
【算法练习】leetcode链表算法题合集
链表总结 增加表头元素倒数节点,使用快慢指针环形链表(快慢指针)合并有序链表,归并排序LRU缓存 算法题 删除链表元素 删除链表中的节点 LeetCode237. 删除链表中的节点 复制后一个节点的值,删除后面的节点&#x…...
2023.12.28每日一题
LeetCode每日一题 2735.收集巧克力 2735. 收集巧克力 - 力扣(LeetCode) 介绍 看题目看不懂,在评论区看到一个大哥解释,瞬间明白了。 一张桌子上有n件商品围成一圈,每件都有一个价签,它们构成数组nums。…...
231227-9步在RHEL8.8配置本地yum源仓库
Seciton 1:参考视频 RHEL8配置本地yum源仓库-安徽迪浮_哔哩哔哩_bilibili Seciton 2:具体操作 🎯 第1步:查看光驱文件/dev/sr0是否已经挂载?此处已挂在 [lgklocalhost ~]$ df -h 🎯 第1步:查看…...
5. 创建型模式 - 单例模式
亦称: 单件模式、Singleton 意图 单例模式是一种创建型设计模式, 让你能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点。 问题 单例模式同时解决了两个问题, 所以违反了单一职责原则: 保证一个类只有一…...
机器学习之人工神经网络(Artificial Neural Networks,ANN)
人工神经网络(Artificial Neural Networks,ANN)是机器学习中的一种模型,灵感来源于人脑的神经网络结构。它由神经元(或称为节点)构成的层级结构组成,每个神经元接收输入并生成输出,这些输入和输出通过权重进行连接。 人工神经网络(ANN)是一种模仿生物神经系统构建的…...
GetLastError()详细介绍
GetLastError() 是 Windows 操作系统提供的一个函数,用于获取调用线程最近一次发生的错误码。这个函数的定义如下: DWORD GetLastError(void); 调用 GetLastError() 函数可以帮助开发人员在发生错误时获取错误的详细信息,从而进行适当的错…...
【unity3D-粒子系统】粒子系统主模块-Particle System篇
💗 未来的游戏开发程序媛,现在的努力学习菜鸡 💦本专栏是我关于游戏开发的学习笔记 🈶本篇是unity的粒子系统主模块-Particle System 基础知识 Particle System 介绍:粒子系统的主模块,是必需的模块&#x…...
Windows搭建FTP服务器教学以及计算机端口介绍
目录 一. FTP服务器介绍 FTP服务器是什么意思? 二.Windows Service 2012 搭建FTP服务器 1.开启防火墙 2.创建组 编辑3.创建用户 4.用户绑定组 5.安装ftp服务器 编辑6.配置ftp服务器 7.配置ftp文件夹的权限 8.连接测试 三.计算机端口介绍 什么是网络…...
安防视频监控系统EasyCVR实现H.265视频在3秒内起播的注意事项
可视化云监控平台/安防视频监控系统EasyCVR视频综合管理平台,采用了开放式的网络结构,可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集中存储、云存储等丰富的视频能力,同时…...
CNN实现对手写字体的迭代
导入库 import torchvision import torch from torchvision.transforms import ToTensor from torch import nn import matplotlib.pyplot as plt 导入手写字体数据 train_dstorchvision.datasets.MNIST(data/,trainTrue,transformToTensor(),downloadTrue) test_dstorchvis…...
docker学习笔记01-安装docker
1.Docker的概述 用Go语言实现的开源应用项目(container);克服操作系统的笨重;快速部署;只隔离应用程序的运行时环境但容器之间可以共享同一个操作系统;Docker通过隔离机制,每个容器间是互相隔离…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
