java spring 11 推断构造方法 createBeanInstance

1.doCreateBean方法:这一部分

	BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {// 有可能在本Bean创建之前,就有其他Bean把当前Bean给创建出来了(比如依赖注入过程中)instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {// 创建Bean实例instanceWrapper = createBeanInstance(beanName, mbd, args);}

2.createBeanInstance方法:

代码逻辑如下:1.如果bean定义中存在 InstanceSupplier ,会使用这个回调接口创建对象(应该是3.X以后新加的,3.X的源码中没有)
2.根据配置的factoryMethodName或factory-mtehod创建bean
3.解析构造函数并进行实例化
		protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {// 解析classClass<?> beanClass = resolveBeanClass(mbd, beanName);//确保class不为空,并且访问权限为publicif (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());}//配置的一种特殊的callback回调方法,通过这个callback创建beanSupplier<?> instanceSupplier = mbd.getInstanceSupplier();if (instanceSupplier != null) {return obtainFromSupplier(instanceSupplier, beanName);}//通过工厂方法创建if (mbd.getFactoryMethodName() != null)  {return instantiateUsingFactoryMethod(beanName, mbd, args);}// 一个类可能有多个构造器,所以Spring得根据参数个数、类型确定需要调用的构造器// 在使用构造器创建实例后,Spring会将解析过后确定下来的构造器或工厂方法保存在缓存中,避免再次创建相同bean时再次解析boolean resolved = false;boolean autowireNecessary = false;if (args == null) {synchronized (mbd.constructorArgumentLock) {if (mbd.resolvedConstructorOrFactoryMethod != null) {//已经解析过class的构造器resolved = true;autowireNecessary = mbd.constructorArgumentsResolved;}}}if (resolved) {//已经解析过class的构造器,使用已经解析好的构造器if (autowireNecessary) {//构造函数自动注入return autowireConstructor(beanName, mbd, null, null);}else {//使用默认构造器return instantiateBean(beanName, mbd);}}// 需要根据参数解析、确定构造函数Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);// 解析的构造器不为空 || 注入类型为构造函数自动注入 || bean定义中有构造器参数 || 传入参数不为空if (ctors != null ||mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {//构造函数自动注入return autowireConstructor(beanName, mbd, ctors, args);}// 使用默认构造器return instantiateBean(beanName, mbd);}

2.1
2.2.obtainFromSupplier方法:

	protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {Object instance;String outerBean = this.currentlyCreatedBean.get();this.currentlyCreatedBean.set(beanName);try {instance = instanceSupplier.get();}finally {if (outerBean != null) {this.currentlyCreatedBean.set(outerBean);}else {this.currentlyCreatedBean.remove();}}if (instance == null) {instance = new NullBean();}BeanWrapper bw = new BeanWrapperImpl(instance);initBeanWrapper(bw);return bw;}

instantiateUsingFactoryMethod:

	protected BeanWrapper instantiateUsingFactoryMethod(String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {// 使用factoryBean来实例化对象return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);}
	public BeanWrapper instantiateUsingFactoryMethod(String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {BeanWrapperImpl bw = new BeanWrapperImpl();this.beanFactory.initBeanWrapper(bw);Object factoryBean;Class<?> factoryClass;boolean isStatic;// 注意,这里拿到的是factoryBeanName,而不是factoryMethodName,比如AppConfig对象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();}this.beanFactory.registerDependentBean(factoryBeanName, beanName);factoryClass = factoryBean.getClass();isStatic = false;}else {// It's a static factory method on the bean class.// static的@Bean方法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);}}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);}}// 找到对应的@Bean方法,由于可能参数重载,所以有可能会有多个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 singletonListcandidates.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;}}Deque<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 {// 根据参数类型和参数名找BeanString[] 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 ArrayDeque<>(1);}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 on class [" + factoryClass.getName() + "]: " +(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() + "' on class [" +factoryClass.getName() + "]: needs to have a non-void return type!");}else if (ambiguousFactoryMethods != null) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Ambiguous factory method matches found on class [" + factoryClass.getName() + "] " +"(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;}

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

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

相关文章

Open CASCADE 教程 – AIS:自定义呈现

文章目录 开始 (Getting Started)呈现构建器 (Presentation builders)基元数组 (Primitive arrays)基元外观 (Primitive aspects)二次构建器 (Quadric builders)计算选择 (Computing selection)突出显示选择所有者 (Highlighting selection owner)突出显示的方法 (Highlighting…

day10-Set集合

1.Set 那接下来我们来看Collection单列集合体系的第二部分 Set集合。 1.1 Set集合概述和特点 Set集合特点 1.可以去除重复 2.存取顺序不一致 3.没有带索引的方法&#xff0c;所以不能使用普通fori循环遍历&#xff0c;也不能通过索引来获取&#xff0c;删除Set集合里面的元…

【大数据】HDFS、HBase操作教程(含指令和JAVA API)

目录 1.前言 2.HDFS 2.1.指令操作 2.2.JAVA API 3.HBase 3.1.指令操作 3.2.JAVA API 1.前言 本文是作者大数据专栏系列的其中一篇&#xff0c;前文中已经详细聊过分布式文件系统HDFS和分布式数据库HBase了&#xff0c;本文将会是它们的实操讲解。 HDFS相关前文&#x…

Python 潮流周刊#50:我最喜欢的 Python 3.13 新特性!

本周刊由 Python猫 出品&#xff0c;精心筛选国内外的 250 信息源&#xff0c;为你挑选最值得分享的文章、教程、开源项目、软件工具、播客和视频、热门话题等内容。愿景&#xff1a;帮助所有读者精进 Python 技术&#xff0c;并增长职业和副业的收入。 本期分享了 12 篇文章&…

哈希算法在区块链中的应用

哈希算法是区块链技术的核心组件之一&#xff0c;它确保了区块链数据的不可篡改性和安全性。在本文中&#xff0c;我们将探讨哈希算法的基本原理&#xff0c;以及它在区块链中的具体应用。 哈希算法的基本原理 哈希算法是一种数学函数&#xff0c;它接收输入&#xff08;或“消…

【Apache Doris】周FAQ集锦:第 3 期

【Apache Doris】周FAQ集锦&#xff1a;第 3 期 SQL问题数据操作问题运维常见问题其它问题关于社区 欢迎查阅本周的 Apache Doris 社区 FAQ 栏目&#xff01; 在这个栏目中&#xff0c;每周将筛选社区反馈的热门问题和话题&#xff0c;重点回答并进行深入探讨。旨在为广大用户和…

【平台搭建+数据处理+数据可视化】

第一部分:大数据平台搭建 一、Hadoop 1、完全分布式Hadoop集群搭建: (1)在master主节点将/opt目录下的Hadoop安装包hadoop-3.1.4.tar.gz解压到/opt/software目录下。 mkdir -p /opt/software tar -zxf /opt/hadoop-3.1.4.tar.gz -C /opt/software (2)创建Hadoop临时数…

【每日随笔】人性 - 能屈能伸 ( 君子之道 能屈能伸 )

文章目录 一、君子之道 能屈能伸1、含义分析2、能屈3、能伸4、最佳实践 二、能屈能伸 - 应用场景1、个人层面2、国家层面 柳树随风摇曳 , 风再大也不会断 , 能屈能伸 ; 一个人行为处事 , 不能一直强硬 , 也不能一直妥协 , 该妥协的时候就要妥协让步 , 该硬的时候就要用于斗争 …

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-15.5讲 GPIO中断实验-通用中断驱动编写

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

学习Uni-app开发小程序Day8

前面几天&#xff0c;学习了vue的button组件、input组件&#xff0c;vue模版语法、计算属性等&#xff0c;在昨天又根据前面学习的&#xff0c;跟着做了一个小的购物车功能&#xff0c;今天学习了侦听器和计算属性 计算属性 computed computed是一个只读的状态,如果要修改…

Golang | Leetcode Golang题解之第77题组合

题目&#xff1a; 题解&#xff1a; func combine(n int, k int) (ans [][]int) {// 初始化// 将 temp 中 [0, k - 1] 每个位置 i 设置为 i 1&#xff0c;即 [0, k - 1] 存 [1, k]// 末尾加一位 n 1 作为哨兵temp : []int{}for i : 1; i < k; i {temp append(temp, i)}t…

uniapp音乐播放整理

一、前置知识点 1.1 音频组件控制-uni.createInnerAudioContext() 创建并返回内部 audio 上下文 innerAudioContext 对象。 主要用于当前音乐播放&#xff1b; 1.1.1 innerAudioContext属性 属性类型说明只读平台差异说明srcString音频的数据链接&#xff0c;用于直接播放…

深入探索CSS3 appearance 属性:解锁原生控件的定制秘密

CSS3 的 appearance 属性&#xff0c;作为一个强大的工具&#xff0c;让我们得以细致入微地控制元素的外观&#xff0c;特别是对于那些具有平台特定样式的表单元素&#xff0c;如按钮、输入框等。本文不仅会深入解析 appearance 属性的基本工作原理和使用场景&#xff0c;还将通…

TypeScript在前端项目的渐进式采用策略

渐进式采用 TypeScript 在前端项目中的策略通常包括: 引入TypeScript 如果我们有一个简单的JavaScript模块utils.js&#xff0c;它包含一个函数用于计算两数之和&#xff1a; // utils.js export function add(a, b) {return a b; }首先&#xff0c;我们将文件扩展名改为.t…

vue的css深度选择器 deep /deep/

作用及概念 当 <style> 标签有 scoped 属性时&#xff0c;它的 CSS 只作用于当前组件中的元素&#xff0c;父组件的样式将不会渗透到子组件。在vue中是这样描述的&#xff1a; 处于 scoped 样式中的选择器如果想要做更“深度”的选择&#xff0c;也即&#xff1a;影响到子…

vscode+clangd阅读Linux内核源码

1. 禁用或卸载官方C/C插件. 2. 安装clangd插件 3. 清除之前的产物 4. 生成.config文件 5.编译生成内核镜像 6.编译内核模块 7.编译设备树文件 8.生成compile_commands.json文件 运行上述命令后&#xff0c;在内核源码根目录生成了compile_commands.json文件 9.设置clangd插…

Verlog-串口发送-FPGA

Verlog-串口发送-FPGA 引言&#xff1a; ​ 随着电子技术的不断进步&#xff0c;串口通信已成为嵌入式系统和计算机外设中一种广泛使用的异步通信方式。串口通信因其简单性、可靠性以及对硬件资源的低要求&#xff0c;在数据传输领域扮演着重要角色。在FPGA&#xff08;现场可编…

记录一个git无法push的问题

今天准备写新功能&#xff0c;想把之前的代码push到远程仓库&#xff0c;但是git突然就不工作了&#xff0c;报错如下 OpenSSL SSL_connect: Connection was reset in connection to gitee.com:443 因为我昨天把项目目录改了&#xff0c;以为是目录修改的问题&#xff0c;但是…

读天才与算法:人脑与AI的数学思维笔记25_涌现理论

1. 人工智能新闻 1.1. 人工智能新闻报道算法的核心是如何将未经处理的原始数据转换成新闻报道 1.2. 很少有记者为美联社决定使用机器来帮助报道这些新闻持反对意见 1.2.1. 像“Wordsmith”这样的算法&#xff0c;具有自动化的洞察力、科学的叙事能力&#xff0c;现在正被应用…

处理RESTful服务中不完整JSON数据的策略

在RESTful服务中&#xff0c;客户端与服务器之间的数据交换经常通过JSON格式进行。然而&#xff0c;客户端传递的JSON数据可能并不总是包含服务器端数据结构所需的所有字段。这种情况可能导致自动反序列化工具&#xff08;如serde&#xff09;无法直接将JSON数据转换为服务器端…