spring复习:(54)注解配置和xml配置时在bean实例化时的区别

news2024/11/24 2:48:18

一、使用配置文件定义bean时,会调用无参的构造方法:
在这里插入图片描述

而使用@Configuration+@Bean注解时,在bean定义解析时设置了
factoryBeanName和factoryMethodName
在这里插入图片描述
实例化bean时会走如下逻辑:
在这里插入图片描述
instantiateUsingFactoryMethod方法代码如下:
在这里插入图片描述
重载的instantiateUsingFactoryMethod方法代码如下:

	public BeanWrapper instantiateUsingFactoryMethod(
			String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {

		BeanWrapperImpl bw = new BeanWrapperImpl();
		this.beanFactory.initBeanWrapper(bw);

		Object factoryBean;
		Class<?> factoryClass;
		boolean isStatic;

		String factoryBeanName = mbd.getFactoryBeanName();
		if (factoryBeanName != null) {
			if (factoryBeanName.equals(beanName)) {
				throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
						"factory-bean reference points back to the same bean definition");
			}
			factoryBean = this.beanFactory.getBean(factoryBeanName);
			if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
				throw new ImplicitlyAppearedSingletonException();
			}
			factoryClass = factoryBean.getClass();
			isStatic = false;
		}
		else {
			// It's a static factory method on the bean class.
			if (!mbd.hasBeanClass()) {
				throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
						"bean definition declares neither a bean class nor a factory-bean reference");
			}
			factoryBean = null;
			factoryClass = mbd.getBeanClass();
			isStatic = true;
		}

		Method factoryMethodToUse = null;
		ArgumentsHolder argsHolderToUse = null;
		Object[] argsToUse = null;

		if (explicitArgs != null) {
			argsToUse = explicitArgs;
		}
		else {
			Object[] argsToResolve = null;
			synchronized (mbd.constructorArgumentLock) {
				factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
				if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
					// Found a cached factory method...
					argsToUse = mbd.resolvedConstructorArguments;
					if (argsToUse == null) {
						argsToResolve = mbd.preparedConstructorArguments;
					}
				}
			}
			if (argsToResolve != null) {
				argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve, true);
			}
		}

		if (factoryMethodToUse == null || argsToUse == null) {
			// Need to determine the factory method...
			// Try all methods with this name to see if they match the given arguments.
			factoryClass = ClassUtils.getUserClass(factoryClass);

			List<Method> candidates = null;
			if (mbd.isFactoryMethodUnique) {
				if (factoryMethodToUse == null) {
					factoryMethodToUse = mbd.getResolvedFactoryMethod();
				}
				if (factoryMethodToUse != null) {
					candidates = Collections.singletonList(factoryMethodToUse);
				}
			}
			if (candidates == null) {
				candidates = new ArrayList<>();
				Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
				for (Method candidate : rawCandidates) {
					if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
						candidates.add(candidate);
					}
				}
			}

			if (candidates.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
				Method uniqueCandidate = candidates.get(0);
				if (uniqueCandidate.getParameterCount() == 0) {
					mbd.factoryMethodToIntrospect = uniqueCandidate;
					synchronized (mbd.constructorArgumentLock) {
						mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
						mbd.constructorArgumentsResolved = true;
						mbd.resolvedConstructorArguments = EMPTY_ARGS;
					}
					bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));
					return bw;
				}
			}

			if (candidates.size() > 1) {  // explicitly skip immutable singletonList
				candidates.sort(AutowireUtils.EXECUTABLE_COMPARATOR);
			}

			ConstructorArgumentValues resolvedValues = null;
			boolean autowiring = (mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
			int minTypeDiffWeight = Integer.MAX_VALUE;
			Set<Method> ambiguousFactoryMethods = null;

			int minNrOfArgs;
			if (explicitArgs != null) {
				minNrOfArgs = explicitArgs.length;
			}
			else {
				// We don't have arguments passed in programmatically, so we need to resolve the
				// arguments specified in the constructor arguments held in the bean definition.
				if (mbd.hasConstructorArgumentValues()) {
					ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
					resolvedValues = new ConstructorArgumentValues();
					minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
				}
				else {
					minNrOfArgs = 0;
				}
			}

			LinkedList<UnsatisfiedDependencyException> causes = null;

			for (Method candidate : candidates) {

				int parameterCount = candidate.getParameterCount();
				if (parameterCount >= minNrOfArgs) {
					ArgumentsHolder argsHolder;

					Class<?>[] paramTypes = candidate.getParameterTypes();
					if (explicitArgs != null) {
						// Explicit arguments given -> arguments length must match exactly.
						if (paramTypes.length != explicitArgs.length) {
							continue;
						}
						argsHolder = new ArgumentsHolder(explicitArgs);
					}
					else {
						// Resolved constructor arguments: type conversion and/or autowiring necessary.
						try {
							String[] paramNames = null;
							ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
							if (pnd != null) {
								paramNames = pnd.getParameterNames(candidate);
							}
							argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw,
									paramTypes, paramNames, candidate, autowiring, candidates.size() == 1);
						}
						catch (UnsatisfiedDependencyException ex) {
							if (logger.isTraceEnabled()) {
								logger.trace("Ignoring factory method [" + candidate + "] of bean '" + beanName + "': " + ex);
							}
							// Swallow and try next overloaded factory method.
							if (causes == null) {
								causes = new LinkedList<>();
							}
							causes.add(ex);
							continue;
						}
					}

					int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
							argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
					// Choose this factory method if it represents the closest match.
					if (typeDiffWeight < minTypeDiffWeight) {
						factoryMethodToUse = candidate;
						argsHolderToUse = argsHolder;
						argsToUse = argsHolder.arguments;
						minTypeDiffWeight = typeDiffWeight;
						ambiguousFactoryMethods = null;
					}
					// Find out about ambiguity: In case of the same type difference weight
					// for methods with the same number of parameters, collect such candidates
					// and eventually raise an ambiguity exception.
					// However, only perform that check in non-lenient constructor resolution mode,
					// and explicitly ignore overridden methods (with the same parameter signature).
					else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight &&
							!mbd.isLenientConstructorResolution() &&
							paramTypes.length == factoryMethodToUse.getParameterCount() &&
							!Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {
						if (ambiguousFactoryMethods == null) {
							ambiguousFactoryMethods = new LinkedHashSet<>();
							ambiguousFactoryMethods.add(factoryMethodToUse);
						}
						ambiguousFactoryMethods.add(candidate);
					}
				}
			}

			if (factoryMethodToUse == null || argsToUse == null) {
				if (causes != null) {
					UnsatisfiedDependencyException ex = causes.removeLast();
					for (Exception cause : causes) {
						this.beanFactory.onSuppressedException(cause);
					}
					throw ex;
				}
				List<String> argTypes = new ArrayList<>(minNrOfArgs);
				if (explicitArgs != null) {
					for (Object arg : explicitArgs) {
						argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
					}
				}
				else if (resolvedValues != null) {
					Set<ValueHolder> valueHolders = new LinkedHashSet<>(resolvedValues.getArgumentCount());
					valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
					valueHolders.addAll(resolvedValues.getGenericArgumentValues());
					for (ValueHolder value : valueHolders) {
						String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType()) :
								(value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null"));
						argTypes.add(argType);
					}
				}
				String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes);
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"No matching factory method found: " +
						(mbd.getFactoryBeanName() != null ?
							"factory bean '" + mbd.getFactoryBeanName() + "'; " : "") +
						"factory method '" + mbd.getFactoryMethodName() + "(" + argDesc + ")'. " +
						"Check that a method with the specified name " +
						(minNrOfArgs > 0 ? "and arguments " : "") +
						"exists and that it is " +
						(isStatic ? "static" : "non-static") + ".");
			}
			else if (void.class == factoryMethodToUse.getReturnType()) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Invalid factory method '" + mbd.getFactoryMethodName() +
						"': needs to have a non-void return type!");
			}
			else if (ambiguousFactoryMethods != null) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Ambiguous factory method matches found in bean '" + beanName + "' " +
						"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
						ambiguousFactoryMethods);
			}

			if (explicitArgs == null && argsHolderToUse != null) {
				mbd.factoryMethodToIntrospect = factoryMethodToUse;
				argsHolderToUse.storeCache(mbd, factoryMethodToUse);
			}
		}

		bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
		return bw;
	}

其中包含如下代码:
在这里插入图片描述
instantiate方法代码如下:
在这里插入图片描述
其中的instantiate代码如下:
在这里插入图片描述
可以看到其通过反射的方式调用了factoryBean的factoryMethod方法。

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

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

相关文章

怎么学习JavaWeb开发? - 易智编译EaseEditing

学习JavaWeb开发可以按照以下步骤进行&#xff1a; 掌握Java基础&#xff1a; 在学习JavaWeb开发之前&#xff0c;确保你对Java编程语言有一定的掌握&#xff0c;包括面向对象编程、基本语法、数据类型、流程控制等。 学习HTML、CSS和JavaScript&#xff1a; JavaWeb开发主要…

Thanos工作原理及组件简介

Thanos 简介 Thanos 是一个「开源的&#xff0c;高可用的 Prometheus 系统&#xff0c;具有长期存储能力」。很多知名公司都在使用 Thanos&#xff0c;也是 CNCF 孵化项目的一部分。 Thanos 的一个主要特点就是通过使用对象存储&#xff08;比如 S3&#xff09;可以允许 “无…

苹果safari浏览器播放不了video标签视频

今天遇到了个神奇的问题&#xff0c;视频文件在pc端和安卓手机上播放都没问题&#xff0c;但是在ios上就是播放不了&#xff0c;大概代码如下&#xff1a; 前端代码&#xff1a; <video id"video" width"350" height"500" controls><s…

PMP和软考应该考哪个?

1、信息系统项目管理师和PMP都是国家或国际级别的考试&#xff0c;证书具有通用性。但从考试难度上来说&#xff0c;PMP相对更容易&#xff0c;因为只有一场考试&#xff0c;且题型相对单一。而信息系统项目管理师则需要通过三科考试&#xff0c;包括综合知识、案例分析、论文等…

Hybird App技术解析:混合应用热更新原理

原生应用与混合应用的开发发布 1、原生应用 我们都知道传统原生 APP &#xff0c;整个开发成本非常高、发布周期也比较长。对于需要频繁迭代业务内容的企业来说&#xff0c;无论是更新功能模块还是修复有缺陷的版本&#xff0c;都需要重新测试、重新发版、重新提交第三方应用…

金融领域:产业链知识图谱包括上市公司、行业和产品共3类实体,构建并形成了一个节点10w+,关系边16w的十万级别产业链图谱

项目设计集合&#xff08;人工智能方向&#xff09;&#xff1a;助力新人快速实战掌握技能、自主完成项目设计升级&#xff0c;提升自身的硬实力&#xff08;不仅限NLP、知识图谱、计算机视觉等领域&#xff09;&#xff1a;汇总有意义的项目设计集合&#xff0c;助力新人快速实…

智能井盖:科技赋能城市脚下安全

在智能化飞速发展的今天&#xff0c;智能井盖作为城市基础设施的一部分&#xff0c;正逐渐走进人们的视野。它利用现代科技手段&#xff0c;实现了对城市井盖的实时监控、及时响应和高效管理&#xff0c;为城市管理、市民出行等方面带来了诸多便利。 城市中井盖数量庞大&#x…

ES6基础知识六:你是怎么理解ES6中 Promise的?使用场景?

一、介绍 Promise&#xff0c;译为承诺&#xff0c;是异步编程的一种解决方案&#xff0c;比传统的解决方案&#xff08;回调函数&#xff09;更加合理和更加强大 在以往我们如果处理多层异步操作&#xff0c;我们往往会像下面那样编写我们的代码 doSomething(function(resu…

Springboot+vue 集成openAI智能助手源码分享(适配手机端)

- 演示站&#xff1a;http://tlzcf.vip:8679/ 源码地址&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1a_sGUGW1Q4n3VKbRqlpHrw?pwdtl2u 提取码&#xff1a;tl2u在这里插入代码片

JVM - 运行时数据区域

文章目录 程序计数器栈堆方法区知识延申 -- 字符串常量池 程序计数器 并发情况下&#xff0c;会发生线程之间的上下文切换&#xff0c;当 线程1 的CPU时间片用完后&#xff0c;需要程序计数器记录 线程1 的下一条JVM指令的地址&#xff0c;等下一次 线程1 继续运行的时&#x…

【FPGA】Verilog:模块化组合逻辑电路设计 | 半加器 | 全加器 | 串行加法器 | 子模块 | 主模块

前言&#xff1a;本章内容主要是演示Vivado下利用Verilog语言进行电路设计、仿真、综合和下载 示例&#xff1a;加法器 ​ 功能特性&#xff1a; 采用 Xilinx Artix-7 XC7A35T芯片 配置方式&#xff1a;USB-JTAG/SPI Flash 高达100MHz 的内部时钟速度 存储器&#xff1a;2Mbi…

重新成为合伙人背后,阿里需要蒋凡

监制 | 何玺 排版 | 叶媛 7月21日&#xff0c;阿里巴巴集团发布2023财年年报。据财报信息显示&#xff0c;阿里国际数字商业集团CEO蒋凡和菜鸟集团CEO万霖已成为阿里合伙人。 01 蒋凡重新成为阿里合伙人 该财报数据显示&#xff0c;截至3月31日的2023财年&#xff0c;阿里巴…

JAVA面试总结-Redis篇章(一)——缓存穿透

JAVA面试总结-Redis篇章&#xff08;一&#xff09; Redis缓存穿透解决方案一:缓存空数据&#xff0c;查询返回的数据为空&#xff0c;仍把这个空结果进行缓存![在这里插入图片描述](https://img-blog.csdnimg.cn/157c22930bff43cda2d325978a5ae05b.png)解决方案二&#xff1a;…

UE4/5C++多线程插件制作(十六、Coroutines协程封装)

我们要对协程继续封装制作: 协程是一种计算机程序组件,它允许在某个位置暂停执行,然后在稍后的时间点恢复执行。与传统的函数调用不同,协程可以被多次调用并且能够保留其内部状态,从而允许程序在执行到一定点时暂停,执行其他任务,然后再返回协程继续执行。 在传统的线…

机器学习深度学习——softmax回归(上)

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——线性回归的简洁实现 &#x1f4da;订阅专栏&#xff1a;机器学习&&深度学习 希望文章对你们有所…

CSS动画@animationend

CSS动画 是什么&#xff1f; CSS 中的动画类似于 flash 中的逐帧动画&#xff0c;表现细腻并且非常灵活&#xff0c;使用 CSS 中的动画可以取代许多网页中的动态图像、Flash 动画或者 JavaScript 实现的特殊效果。 这里感兴趣的可以去了解针 动画是什么 常用的css动画属性 :…

C国演义 [第十一章]

第十一章 有效的字母异位词题目理解代码 两数之和题目理解(暴力篇)代码题目理解(哈希篇)代码 有效的字母异位词 力扣链接 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词 注意&#xff1a;若 s 和 t 中每个字符出现的次数都相同&#xff0c;…

华为盘古大模型:能源领域的颠覆性突破

近日&#xff0c;华为盘古大模型在能源领域横空出世&#xff0c;引发了广泛关注和期待。作为一项具有颠覆性影响的技术创新&#xff0c;华为盘古大模型在能源行业中展现出巨大的潜力和前景。其优质的计算能力和智能优化算法&#xff0c;将为能源产业带来翻天覆地的变革。 盘古大…

linxu部署项目(详细教程)

首先我们需要一台虚拟机或者云服务器&#xff08;二选一即可&#xff09; 我们需要在安装jdk与tomcat 安装jdk&#xff0c;去官网下载对应的tar.gz压缩包就行tomcat同理 这里&#xff0c;我们已将下载好的JDK源码包 jdk-8u131-linux-x64.tar.gz 拷贝至 /usr/local/java/ 目录。…

《零基础入门学习Python》第066讲:GUI的终极选择:Tkinter3

今天我们一起来学习三个组件&#xff1a;Checkbutton、Radiobutton 和 LabelFrame。 同样&#xff0c;我们还是通过案例来讲解。 一、Checkbutton Checkbutton&#xff08;多选框&#xff09;。大家都知道什么叫做“翻牌子”&#xff0c;今天的第一个例子就是来写一个翻牌子…