当前位置: 首页 > news >正文

Spring DefaultListableBeanFactory源码分析

目录
一、概述
二、主要功能
三、核心功能解析
Bean定义的存储结构
ConcurrentHashMap的使用和意义
四、总结

一、概述

DefaultListableBeanFactory 是 Spring 框架中的一个核心类,它继承自AbstractAutowireCapableBeanFactory类,实现了 ListableBeanFactory 接口,并提供了一些额外的方法用于注册和获取Bean的定义。该类提供了 Spring 应用上下文中的 bean 定义和实例的管理功能。它是 Spring 容器的基础,负责管理 bean 的生命周期、依赖注入等核心功能。

二、主要功能

  1. Bean 定义管理DefaultListableBeanFactory 存储了所有的 bean 定义,这些定义通常来自于 XML 配置文件、注解或其他配置方式。
  2. Bean 实例化:根据 bean 的定义,容器负责实例化它们。
  3. 依赖注入:容器负责自动装配 bean 之间的依赖关系。
  4. 生命周期管理:容器负责管理 bean 的生命周期,从创建到销毁。
  5. 事件发布:容器负责发布与 bean 相关的各种事件,如初始化、销毁等。

三、关键代码分析

  1. 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 的 FieldMethod 类来访问和修改对象的属性。
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的功能。

相关文章:

  • mvtec3d
  • [架构之路-265]:目标系统 - 设计方法 - 软件工程 - 软件设计 - 如何做好详细设计
  • D9741 PWM控制器电路,定时闩锁、短路保护电路,输出基准电压(2.5V) 采用SOP16封装
  • 【UE5.1】程序化生成Nanite植被
  • 实战10 角色管理
  • redis 从0到1完整学习 (八):QuickList 数据结构
  • Android画布Canvas drawPath绘制跟随手指移动的圆,Kotlin
  • Springcloud Alibaba 使用Canal将MySql数据实时同步到Elasticsearch
  • Git三种方法从远程仓库拉取指定分支
  • Leetcode 2971. Find Polygon With the Largest Perimeter
  • C#实现串口通讯
  • Unity Shader 实现X光效果
  • 【Qt-Event-信号和槽】
  • go 语言程序设计第2章--程序结构
  • JS-图片预览
  • 9月CHINA-PUB-OPENDAY技术沙龙——IPHONE
  • hexo+github搭建个人博客
  • @angular/forms 源码解析之双向绑定
  • C学习-枚举(九)
  • express.js的介绍及使用
  • interface和setter,getter
  • PV统计优化设计
  • Spring Boot MyBatis配置多种数据库
  • 对超线程几个不同角度的解释
  • 关于Java中分层中遇到的一些问题
  • 诡异!React stopPropagation失灵
  • 猴子数据域名防封接口降低小说被封的风险
  • 基于webpack 的 vue 多页架构
  • 快速体验 Sentinel 集群限流功能,只需简单几步
  • 聊聊hikari连接池的leakDetectionThreshold
  • 设计模式 开闭原则
  • 使用common-codec进行md5加密
  • 网络应用优化——时延与带宽
  • 文本多行溢出显示...之最后一行不到行尾的解决
  • 学习笔记TF060:图像语音结合,看图说话
  • ​HTTP与HTTPS:网络通信的安全卫士
  • !!java web学习笔记(一到五)
  • # Java NIO(一)FileChannel
  • $ git push -u origin master 推送到远程库出错
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (10)工业界推荐系统-小红书推荐场景及内部实践【排序模型的特征】
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (delphi11最新学习资料) Object Pascal 学习笔记---第5章第5节(delphi中的指针)
  • (八)c52学习之旅-中断实验
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (超详细)2-YOLOV5改进-添加SimAM注意力机制
  • (七)c52学习之旅-中断
  • (十八)devops持续集成开发——使用docker安装部署jenkins流水线服务
  • (五)关系数据库标准语言SQL
  • (一)Neo4j下载安装以及初次使用
  • (一)认识微服务
  • (转)Java socket中关闭IO流后,发生什么事?(以关闭输出流为例) .
  • .mysql secret在哪_MySQL如何使用索引
  • .NET Core 网络数据采集 -- 使用AngleSharp做html解析
  • .net framework4与其client profile版本的区别