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通过隔离机制,每个容器间是互相隔离…...

龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...

关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...

selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...

华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...

网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...

MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...