一起学SF框架系列5.4-模块Beans-DefaultListableBeanFactory

news2024/11/16 1:19:13

在生成ApplicationContext过程中,AbstractRefreshableApplicationContext.refreshBeanFactory()完成旧BeanFactory关闭,创建新的BeanFactory,即new DefaultListableBeanFactory(…)。然后bean实例化时调用本类的preInstantiateSingletons方法。

类作用

BeanFactory作用是初始化和管理普通bean,因此DefaultListableBeanFactory是实现框架核心功能(IoC)的核心类。

类关系图

在这里插入图片描述
DefaultListableBeanFactory类关系图比较复杂,我们从顶向下梳理:

接口定义说明

AliasRegistry:顶层接口,别名注册表接口,定义了管理bean的别名和名称映射关系的基本方法,如注册registerAlias(String name, String alias)、获取(getAliases(String name))和销毁(removeAlias(String alias))。

SingletonBeanRegistry:顶层接口,单实例bean注册表接口,定义了管理单实例Bean的基本方法,如注册(registerSingleton(String beanName, Object singletonObject))和获取(getSingleton(String beanName)。

BeanFactory:顶层接口,定义了访问bean容器中bean的基本方法,只包括get或判断(如is、contain)类方法。完全不包括BeanFactory是如何初始化并管理bean的方法。从使用者来说,只是按需使用即可,不关注如何实现。

HierarchicalBeanFactory:继承BeanFactory,仅提供访问继承关系BeanFactory的方法,包括etParentBeanFactory()和containsLocalBean(String name)(当前BeanFactory(不是父BeanFactory)是否包含名为name的bean)。

ListableBeanFactory:是BeanFactory接口扩展,定义通过枚举其所有bean实例的方法来访问bean,而不是通过getBean(String beanName)这种单个按名称查找bean。

AutowireCapableBeanFactory:是BeanFactory接口扩展,定义具备自动装配能力的BeanFactory的实现方法。

ConfigurableBeanFactory:定义普通配置模式下BeanFactory的实现方法,如解析bean配置和bean的初始化。

ConfigurableListableBeanFactory:继承了接口ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory,并增加定义了分析和修改bean定义以及预实例化单实例bean的方法。

BeanDefinitionRegistry:BeanDefinition注册表接口,定义对BeanDefinition(即bean的元数据)进行管理的方法。

SimpleAliasRegistry

实现接口AliasRegistry(bean alias存取及相关操作)。

DefaultSingletonBeanRegistry

主要实现单实例bean的缓存池,包括bean依赖关系管理(关系注册和销毁)。本类方法大量采用了synchronized存取缓存池(集合)。
继承于SimpleAliasRegistry,并实现接口SingletonBeanRegistry(单实例bean的存取及相关操作)

FactoryBeanRegistrySupport

单实例bean管理中用到的关于factoryBean的相关方法实现。

AbstractBeanFactory

AbstractBeanFactory主要实现ConfigurableBeanFactory接口功能。BeanFactory大多数功能在该类实现,但核心方法createBean需在子类实现。

AbstractAutowireCapableBeanFactory

继承AbstractBeanFactory,并实现接口AutowireCapableBeanFactory,即自动装配相关功能在该类实现。
核心方法createBean在该类实现。

DefaultListableBeanFactory

继承AbstractAutowireCapableBeanFactory,主要实现接口ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable。其中ConfigurableListableBeanFactory接口中的AutowireCapableBeanFactory, ConfigurableBeanFactory均在祖先类实现了,因此只需实现ListableBeanFactory接口方法。BeanDefinitionRegistry接口全部在这里实现。

类实现

DefaultListableBeanFactory继承于AbstractAutowireCapableBeanFactory,大多数bean的创建、初始化等实现已在祖先类实现。本类主要实现BeanDefinitionRegistry接口和ListableBeanFactory接口。

DefaultListableBeanFactory(@Nullable BeanFactory parentBeanFactory)

DefaultListableBeanFactory构建类,实际构建在父类AbstractAutowireCapableBeanFactory完成,核心动作是动态生成子类的对象instantiationStrategy(CglibSubclassingInstantiationStrategy 用cgilib动态创建子类)。
DefaultListableBeanFactory构建代码:

	public DefaultListableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
		super(parentBeanFactory);
	}

父类AbstractAutowireCapableBeanFactory构建代码:

	public AbstractAutowireCapableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
		this();
		setParentBeanFactory(parentBeanFactory);
	}
	public AbstractAutowireCapableBeanFactory() {
		super();
		ignoreDependencyInterface(BeanNameAware.class);
		ignoreDependencyInterface(BeanFactoryAware.class);
		ignoreDependencyInterface(BeanClassLoaderAware.class);
		//bean实例化器 
		this.instantiationStrategy = new CglibSubclassingInstantiationStrategy();
	}

注1:CglibSubclassingInstantiationStrategy是Bean真正初始化类,详见https://blog.csdn.net/davidwkx/article/details/131053503

preInstantiateSingletons

该方法是启动过程中spring对单实例bean初始化的入口。

	@Override
	public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}

		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) {
			//所有bean定义都统一成RootBeanDefinition 注1
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			//非抽象类、非延迟加载且是Singleton的bean进行初始化
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				//FactoryBean初始化
				if (isFactoryBean(beanName)) {
					//getBean通过有无前缀FACTORY_BEAN_PREFIX 识别是否FactoryBean 注2
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					//FactoryBean中bean默认是延迟创建的,如果FactoryBean实现了SmartFactoryBean,重载isEagerInit()返回true,则表示立即对FactoryBean中的bean进行创建 注3
					if (bean instanceof SmartFactoryBean<?> smartFactoryBean && smartFactoryBean.isEagerInit()) {
						//FactoryBean创建bean
						getBean(beanName);
					}
				}
				//普通bean初始化
				else {
					getBean(beanName);
				}
			}
		}

		//如果bean实现了SmartInitializingSingleton接口,则在初始化后回调afterSingletonsInstantiated
		// Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton smartSingleton) {
				StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
						.tag("beanName", beanName);
				smartSingleton.afterSingletonsInstantiated();
				smartInitialize.end();
			}
		}
	}

注1:bean定义相关见:
注2:getBean(beanName)在AbstractBeanFactory实现,实际是调用AbstractBeanFactory.doGetBean(beanName, null, null, false),详见:https://blog.csdn.net/davidwkx/article/details/130963899
注3:如果beanName是FactoryBean的名称,getBean(“&”+beanName) 是获取 FactoryBean 本身,而getBean(beanName) 获取的是 FactoryBean 创建出来的 bean 实例。

resolveDependency / doResolveDependency

解析指定beanName对应的属性,并将解析到的属性名放入autowiredBeanNames,根据类型查找依赖关系

	@Override
	@Nullable
	public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

		descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
		if (Optional.class == descriptor.getDependencyType()) {
			// Optional类型的注入处理
			return createOptionalDependency(descriptor, requestingBeanName);
		}
		else if (ObjectFactory.class == descriptor.getDependencyType() ||
				ObjectProvider.class == descriptor.getDependencyType()) {
			// ObjectFactory类型的注入处理
			return new DependencyObjectProvider(descriptor, requestingBeanName);
		}
		else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
			// Jsr330注解的注入处理
			return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
		}
		else {
			Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
					descriptor, requestingBeanName);
			if (result == null) {
				//非延迟加载的常规注入处理
				result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
			}
			return result;
		}
	}

	@Nullable
	public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

		InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
		try {
			Object shortcut = descriptor.resolveShortcut(this);
			if (shortcut != null) {
				return shortcut;
			}

			// @Value注解的注入
			Class<?> type = descriptor.getDependencyType();
			Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
			if (value != null) {
				if (value instanceof String strValue) {
					// 占位符解析
					String resolvedValue = resolveEmbeddedValue(strValue);
					BeanDefinition bd = (beanName != null && containsBean(beanName) ?
							getMergedBeanDefinition(beanName) : null);
					// EL表达式
					value = evaluateBeanDefinitionString(resolvedValue, bd);
				}
				// 转换类型
				TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
				try {
					return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
				}
				catch (UnsupportedOperationException ex) {
					// A custom TypeConverter which does not support TypeDescriptor resolution...
					return (descriptor.getField() != null ?
							converter.convertIfNecessary(value, type, descriptor.getField()) :
							converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
				}
			}

			//解析多个bean,例如List、set、Map
			Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
			if (multipleBeans != null) {
				return multipleBeans;
			}

			// 依赖查询
			Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
			if (matchingBeans.isEmpty()) {
				if (isRequired(descriptor)) {
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				return null;
			}
			String autowiredBeanName;
			Object instanceCandidate;
			// 如果有多个匹配的Bean,就根据方法名称进行匹配
			if (matchingBeans.size() > 1) {
				autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
				if (autowiredBeanName == null) {
					if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
						return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
					}
					else {
						// In case of an optional Collection/Map, silently ignore a non-unique case:
						// possibly it was meant to be an empty collection of multiple regular beans
						// (before 4.3 in particular when we didn't even look for collection beans).
						return null;
					}
				}
				instanceCandidate = matchingBeans.get(autowiredBeanName);
			}
			else {
				// We have exactly one match.
				Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
				autowiredBeanName = entry.getKey();
				instanceCandidate = entry.getValue();
			}

			if (autowiredBeanNames != null) {
				autowiredBeanNames.add(autowiredBeanName);
			}
			if (instanceCandidate instanceof Class) {
				instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
			}
			Object result = instanceCandidate;
			if (result instanceof NullBean) {
				if (isRequired(descriptor)) {
					raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
				}
				result = null;
			}
			if (!ClassUtils.isAssignableValue(type, result)) {
				throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
			}
			return result;
		}
		finally {
			ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
		}
	}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网安笔记12 IPsec

IPSec 基于通信IP环境下一种端到端&#xff0c;保证数据安全的机制 包含 两个安全协议&#xff0c;一个密钥管理协议&#xff0c; 标准价秘密技术为基础 DES/其他分组加密算法键值hash算法认证公钥有效的数字证书 AH协议提供信息源验证、完整性保证ESP提供信息源验证、机密…

华为OD机试真题 JavaScript 实现【求解立方根】【牛客练习题】

一、题目描述 计算一个浮点数的立方根&#xff0c;不使用库函数。保留一位小数。 数据范围&#xff1a;∣val∣≤20 。 二、输入描述 待求解参数&#xff0c;为double类型&#xff08;一个实数&#xff09; 三、输出描述 输出参数的立方根。保留一位小数。 四、解题思路…

Git工作流(随笔)

目录 前言 一、工作流概述 1、概念 2、分类 二、集中式工作流 1、概述 2、介绍 3、操作过程 三、功能分支工作流 1、概述 2、介绍 3、操作过程 1&#xff09;创建远程分支 2&#xff09;删除远程分支 四、GitFlow工作流 1、概述 2、介绍 3、操作过程 五、Forki…

Linux系统:CentOS编译Linux内核

目录 一、实验 1.下载内核 2.解压内核源码 3.配置依赖的环境 4.进入源码目录&#xff0c;使用make menuconfig开启菜单选项&#xff0c;手动选择内核功能 5.编译内核 6.安装模块 7.安装内核 8.验证新内核版本 一、实验 1.下载内核 &#xff08;1&#xff09;官网下载…

010:vue中el-table 隐藏表头的两种方法

第010个 查看专栏目录: VUE — element UI echarts&#xff0c;openlayers&#xff0c;cesium&#xff0c;leaflet&#xff0c;mapbox&#xff0c;d3&#xff0c;canvas 免费交流社区 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例…

【Kubernetes存储篇】StorageClass存储类动态生成PV详解

文章目录 一、StorageClass存储类理论二、案例&#xff1a;Storageclass存储类实战演示1、搭建NFS服务端2、搭建NFS供应商(provisioner)3、创建StorageClass存储类4、创建PVC&#xff0c;通过StorageClass动态生成PV5、创建Pod挂载PVC 三、步骤总结 一、StorageClass存储类理论…

web测试工程师的工作职责

web测试工程师的工作职责1 职责: 1、 负责数据平台产品的测试工作&#xff0c;参与产品需求分析&#xff0c;负责方案制定,并能预先评估项目风险&#xff0c;确保测试活动的顺利开展; 2、 深入理解系统内部的设计原理&#xff0c;并能从测试的角度提供优化意见; 3、 根据产品需…

LVS+Keepalived 高可用群集实战部署

目录 前言 一、Keepalived工具介绍 1、Keepalived的作用 2、 Keepalived体系主要模块 二、keepalived工作原理 1、VRRP &#xff08;虚拟路由冗余协议&#xff09; 2、VRRP &#xff08;虚拟路由冗余协议&#xff09; &#xff08;1&#xff09;keepalived.conf是主配置文…

qt 使用qtpdfium实现读取pdf文件

此处仅作为笔记和配置指导。 要想获取源码可Git hub上下载&#xff0c;这里推荐一个&#xff1a;QtPdfium_Build_Source: 基于Google pdfium 库&#xff0c;可编译和编译好的Qtpdfium 库&#xff0c;用于加载pdf文件进行预览 (gitee.com) 目前小编根据推荐的编译方法&#xf…

STM32F0实现数字化SPWM纯正弦波逆变器

一、理论基础 所谓SPWM&#xff0c;就是通过只有开关两个状态&#xff08;离散&#xff0c;数字的&#xff09;的PWM序列产生正弦波&#xff08;连续&#xff0c;模拟的&#xff09;的方法。其理论基础一句话就能说明白&#xff1a;冲量相等而形状不同的窄脉冲加在具有惯性的环…

golang语法的注意事项

目录 1.源文件以.go结尾2.过文件只能存在一个mian 函数 (入口函数)3. go严格区分大小写4. golang的每行代码是一个语句 默认存在 ; 不需要自己写了5. golang 是每一行每一行的执行的 不要把多个语句写在一行6. 定义变量 或是导入的包未使用 无法同过编译7. {} 都是成对出现 为了…

Xtrak 塔克小车巡线代码以及红绿灯识别相关小改动

做的小改动&#xff1a; 只更改了xtark_follow_line.py 增加了一次HSV分割来做红绿灯识别&#xff08;建议到时候用手机或者平板显示红色或者绿色图片&#xff09;&#xff0c;红绿图片&#xff1a; 将检测道路位置的方式从重心变为最接近屏幕中心的道路像素点。 检测不到道路之…

ubuntu 22.04部署dzzoffice及安装onlyoffice插件

目录 一、配置阿里源 二、安装数据库 三、安装依赖组件 &#xff08;一&#xff09;安装php7.4 &#xff08;二&#xff09;安装apache2 四、下载 dzzoffice 五、安装dzzoffice 六、安装onlyoffice插件 &#xff08;一&#xff09;从github下载小胡版onlyoffice替代原来…

如何学习及计算机编程,入门看这一篇就够了---以c语言为例

信息时代&#xff0c;计算机变成不再是专业性很强的一门学科&#xff0c;更多的是变成了一种工具 用计算机爬取信息&#xff08;爬虫&#xff09;进行数据分析&#xff0c;数据可视化&#xff08;大数据的某个方面&#xff09;处理海量的数据&#xff0c;如excel&#xff08;百…

声音生成项目(4)——从VariantAutoencoder(VAE)到VQ-VAE矢量量化变分编码器

文章目录 论文介绍步骤具体讲解自定义矢量量化层获取最近距离的码字的索引计算推导损失函数相关参考 矢量量化层的代码实现完整代码实现 论文介绍 不同于变分编码器和自动编码器&#xff0c;vq-vae中的latent space是离散的&#xff0c;并不是连续的&#xff0c;这能够避免后验…

第3章“程序的机器级表示”:理解指针

指针是 C 语言的一个重要特色。它们提供一种统一方式&#xff0c;能够远程访问数据结构。 指针基本的概念其实非常简单&#xff0c;下面的代码说明了许多这样的概念&#xff1a; struct str { /* Example Structure */int t;char v; };union uni { /* Example Union */int t;…

大厂C++面试基础题第1辑——虚函数七题精讲之一

> “虚函数的作用” 是面向对象的C编程最基础也最核心的知识点&#xff0c;如果不能无法正确回答本题&#xff0c;则只此一题&#xff0c;不管大厂还是小厂&#xff0c;都铁定无缘了。 概述 “虚函数” 是 C面向对象三最&#xff1a;最基础、最重要、最关键的知识点。我们从…

什么是Vue的Vite构建工具?如何使用Vite进行项目开发

什么是Vue的Vite构建工具&#xff1f;如何使用Vite进行项目开发 介绍 Vite是一个由Vue.js核心团队开发的构建工具。它的目标是提供一种快速的开发体验&#xff0c;同时保持生产环境的稳定性和可靠性。Vite使用了ES模块作为开发环境的原生模块格式&#xff0c;通过在开发服务器…

C++11中的关键字constexpr

文章目录 1、constexpr修饰普通变量2、constexpr修饰函数3、constexpr修饰类的构造函数 constexpr 关键字的功能是使指定的常量表达式获得在程序编译阶段计算出结果的能力&#xff0c;而不必等到程序运行阶段。C 11 标准中&#xff0c;constexpr 可用于修饰普通变量、函数&…

【Leetcode】DP | 序列及子数组问题

300 最长递增子序列 求数组最长严格递增子序列的长度。 D [ i ] D[i] D[i]代表以 n u m s [ i ] nums[i] nums[i]结尾的最长递增子序列的长度。 D [ i ] max ⁡ j < i , n u m s [ i ] > n u m s [ j ] ( D [ j ] 1 ) D[i] \max_{j < i,\ nums[i]>nums[j]}(D[…