深入剖析Spring框架:推断构造方法与@Bean注解的内部机制

news2024/11/25 20:38:00

你好,我是柳岸花开。

Spring框架作为Java开发中广泛使用的基础架构,其设计精巧、功能强大,尤其是其依赖注入(DI)和控制反转(IoC)特性,极大地提高了代码的可维护性和可测试性。本文将深入探讨Spring中的推断构造方法和@Bean注解的内部机制,帮助读者更深入地理解Spring框架。

推断构造方法

在Spring框架中,当我们定义一个Bean时,Spring容器需要根据类中的构造方法来实例化Bean。如果类中只有一个无参构造方法,Spring容器将使用它来创建实例。然而,当存在多个构造方法时,Spring将如何决定使用哪一个构造方法呢?

构造方法的选择

Spring提供了多种方式来指定使用哪个构造方法:

  1. 无参构造方法:如果没有其他指定,Spring默认使用无参构造方法。
  2. @Autowired注解:可以标记在构造方法上,指示Spring使用该构造方法,并根据参数类型自动注入依赖。
  3. **@Autowired(required=false)**:当标记在构造方法上时,即使没有匹配的Bean,Spring也不会抛出异常。
  4. XML配置:在XML中可以通过标签指定构造方法参数,或者使用 autowire="constructor"让Spring自动寻找Bean作为构造方法参数。

源码解析

Spring容器在创建Bean实例时,会调用AbstractAutowireCapableBeanFactory类的createBeanInstance()方法。该方法首先检查BeanDefinition是否绑定了Supplier,或者是否存在工厂方法名。如果这些条件都不满足,Spring将尝试自动构造Bean,即调用autowireConstructor()方法。 在autowireConstructor()方法中,Spring会检查是否指定了具体的构造方法或构造方法参数值。如果没有,它将找出所有可用的构造方法,并根据参数个数进行排序,优先选择参数个数最多的构造方法。然后,Spring会遍历每个构造方法,根据参数类型寻找匹配的Bean。如果找到匹配的构造方法,Spring将计算一个匹配分数,以确定最佳匹配。

@Bean注解

@Bean注解允许开发者以编程方式定义Bean的创建过程。Spring容器会将@Bean注解的方法解析成BeanDefinition,并在启动时调用这些方法来创建Bean。

@Bean与工厂方法

当使用@Bean注解时,Spring会考虑以下几点:

  1. 静态方法:如果 @Bean注解的方法是静态的,Spring会直接调用该方法获取Bean实例。
  2. 非静态方法:如果方法不是静态的,Spring会为该方法创建一个实例,然后调用它来获取Bean实例。
  3. 方法重载:如果存在重载,Spring会根据方法名和参数类型来确定使用哪个方法。

isFactoryMethodUnique属性

在由@Bean生成的BeanDefinition中,有一个重要的属性isFactoryMethodUnique,它表示工厂方法是否唯一。在大多数情况下,@Bean生成的BeanDefinitionisFactoryMethodUniquetrue。但如果出现方法重载,Spring会根据方法名和参数类型来确定使用哪个方法,并可能将isFactoryMethodUnique设置为false

实例化过程

在实例化Bean时,如果isFactoryMethodUniquetrue,Spring将直接使用对应的方法来创建Bean。如果为false,Spring将寻找所有匹配的方法,并根据参数类型和数量进行排序,选择最合适的方法来创建Bean。

 @Bean
 public static AService aService(){
  return new AService();
 }

 @Bean
 public AService aService(BService bService){
  return new AService();
 }

虽然有两个@Bean,但是肯定只会生成一个aService的Bean,那么Spring在处理@Bean时,也只会生成一个aService的BeanDefinition,比如Spring先解析到第一个@Bean,会生成一个BeanDefinition,此时isFactoryMethodUnique为true,但是解析到第二个@Bean时,会判断出来beanDefinitionMap中已经存在一个aService的BeanDefinition了,那么会把之前的这个BeanDefinition的isFactoryMethodUnique修改为false,并且不会生成新的BeanDefinition了。

并且后续在根据BeanDefinition创建Bean时,会根据isFactoryMethodUnique来操作,如果为true,那就表示当前BeanDefinition只对应了一个方法,那也就是只能用这个方法来创建Bean了,但是如果isFactoryMethodUnique为false,那就表示当前BeanDefition对应了多个方法,需要和推断构造方法的逻辑一样,去选择用哪个方法来创建Bean。

总结

本文深入探讨了Spring框架中推断构造方法和@Bean注解的内部机制。通过理解这些机制,我们可以更灵活地使用Spring框架,编写出更加健壮和灵活的应用程序。在下一节课中,我们将继续探索Spring的启动过程,揭示更多关于Spring IoC容器的内部工作机制。

结语

深入理解Spring框架的核心特性对于Java开发者来说非常重要。希望本文能够帮助读者更好地理解Spring的工作原理,并在实际开发中更加得心应手。如果你对Spring框架或者其他技术话题有任何疑问,欢迎在评论区交流讨论。让我们一起进步,探索技术的无限可能。

以上就是对Spring框架中推断构造方法和@Bean注解的深度解析。在下一节公众号文章中,我们将继续深入Spring框架的内部,探索更多令人兴奋的话题。敬请期待!

👇关注我,下期了解👇

Spring启动过程源码分析

alt

回复 222,获取Java面试题合集

关于我

一枚爱折腾的Java程序猿,专注Spring干货。把路上的问题记录下来,帮助那些和我一样的人。

好奇心强,喜欢并深入研究古天文。

崇尚 个人系统创建,做一些时间越长越有价值的事情。思考把时间留下来。

本文由 mdnice 多平台发布

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

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

相关文章

9. Django Admin后台系统

9. Admin后台系统 Admin后台系统也称为网站后台管理系统, 主要对网站的信息进行管理, 如文字, 图片, 影音和其他日常使用的文件的发布, 更新, 删除等操作, 也包括功能信息的统计和管理, 如用户信息, 订单信息和访客信息等. 简单来说, 它是对网站数据库和文件进行快速操作和管…

SpringBoot项目部署到阿里云服务器

部署步骤 步骤分以下: 将SpringBoot项目打包Linux上准备好Java环境、可用的MySql数据库项目上传到服务器启动项目停止项目 1.SpringBoot项目打包 数据库的链接,账户和密码需要和Linux上一致。 如上图打包即可。 2.Linux上准备好Java环境以及Mysql环境…

【数据结构】二叉树知识点详解

树的概念 树是一种非线性的数据结构,它是由n(n>0)个有限结点组成一个具有层次关系的集合有一个特殊的结点,称为根结点,根节点没有前驱结点除根节点外,其余结点被分成M(M>0)个互不相交的集合T1、T2、…

【busybox记录】【shell指令】expand

目录 内容来源: 【GUN】【expand】指令介绍 【busybox】【expand】指令介绍 【linux】【expand】指令介绍 使用示例: 把制表符转化为空格 - 默认输出 把制表符转化为空格 - 修改制表符转空格的个数 把制表符转化为空格 - 修改制表符转空格的个数…

git bash各分支修改内容不同但合并后不显示冲突问题

在跟着廖雪峰老师的git学习时,按部就班的执行明后,发现 而不是出现原文的结果 解决方法: 切换位feature分支,再合并 git switch feature1 git merge master 此时我们发现: 后面再跟着原文敲就可以了

CSS学习笔记之基础教程(二)

上节内容CSS学习笔记之基础教程&#xff08;一&#xff09; 6、边距 6.1 外边距&#xff1a;margin 6.1.1 外边距 marginmargin-topmargin-leftmargin-bottommargin-right <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8…

python-scrapy框架示例

参考&#xff1a;https://blog.csdn.net/qq_44907926/article/details/119531324 创建项目步骤&#xff1a; 1.目标网站:www.itcast.cn 2.安装虚拟环境 pip install virtualenv3.创建虚拟环境 virtualenv --always-copy --system-site-packages venv4.激活虚拟环境 venv\sc…

OCR文本识别模型CRNN

CRNN网络结构 论文地址&#xff1a;https://arxiv.org/pdf/1507.05717 参考&#xff1a;https://blog.csdn.net/xiaosongshine/article/details/112198145 git:https://github.com/shuyeah2356/crnn.pytorch CRNN文本识别实现端到端的不定长文本识别。 CRNN网络把包含三部分&…

推荐5个免费的国内平替版GPT

提起AI&#xff0c;大家第一个想到的就是GPT。 虽然它确实很厉害&#xff0c;但奈何于我们水土不服&#xff0c;使用门槛有些高。 不过随着GPT的爆火&#xff0c;现在AI智能工具已经遍布到各行各业了&#xff0c;随着时间的推移&#xff0c;国内的AI工具也已经“百花盛放”了…

简单了解泛型

基本数据类型和对应的包装类 在Java中, 基本数据类型不是继承自Object, 为了在泛型代码中可以支持基本类型, Java给每个基本类型都对应了一个包装类型. 简单来说就是让基本数据类型也能面向对象.基本数据类型可以使用很多方法, 这就必须让它变成类. 基本数据类型对定的包装类…

Istio 流量管理(请求路由、流量转移、请求重试、流量镜像、故障注入、熔断等)介绍及使用

一、Istio 流量管理 Istio是一个开源的服务网格&#xff0c;它为分布式微服务架构提供了网络层的抽象。它使得服务之间的通信变得更为可靠、安全&#xff0c;并且提供了细粒度的流量管理、监控和策略实施功能。Istio通过在服务之间插入一个透明的代理&#xff08;Envoy&#x…

Unreal游戏GPU参数详解,游戏性能优化再升级

UWA GOT Online For Unreal GPU模式近期全新发布&#xff0c;方便开发者从渲染和带宽的角度进行GPU分析。同时&#xff0c;此次更新中UWA也增加了丰富的GPU参数&#xff0c;涵盖了GPU SoC和GPU Counter模块。这些新增的参数不仅能够帮助Unreal开发者从宏观层面监控GPU的压力状况…

QT-TCP通信

网上的资料太过于书面化&#xff0c;所以看起来有的让人云里雾里&#xff0c;看不懂C-tcpsockt和S-tcpsocket的关系 所以我稍微画了一下草图帮助大家理解两个套接字之间的关系。字迹有的飘逸勉强看看 下面是代码 服务端&#xff1a; MainWindow::MainWindow(QWidget *parent) …

Jira Server 不维护了,如何将 Jira 平滑迁移到阿里云云效

作者&#xff1a;天彤 Atlassian 在 2020 年官方发布公告&#xff0c;从 2021 年起停止 Jira Server 产品的销售&#xff0c;并且在 2024 年彻底停止 Server 端产品的服务支持&#xff0c;这对于国内使用 Jira 产品的企业和研发团队造成了不小的影响。而此时国内很多 DevOps 产…

本地主机访问服务器的Redis -- 配置 ssh 端口转发

前言 在进行Java开发时&#xff0c;高度的依赖 Windows 上的开发软件 idea &#xff0c;那么我们想访问位于服务器上的 redis 怎么办呢&#xff1f;在平时我们想访问位于服务器上的程序&#xff0c;只需要开放它的端口即可&#xff0c;比如我们创建的网站&#xff0c;比如 tomc…

【拆位法 决策包容性 位运算】2871. 将数组分割成最多数目的子数组

本文涉及知识点 拆位法 贪心 位运算 决策包容性 位运算、状态压缩、子集状态压缩汇总 LeetCode2871. 将数组分割成最多数目的子数组 给你一个只包含 非负 整数的数组 nums 。 我们定义满足 l < r 的子数组 nums[l…r] 的分数为 nums[l] AND nums[l 1] AND … AND nums[r…

使用图网络和视频嵌入预测物理场

文章目录 一、说明二、为什么要预测&#xff1f;三、流体动力学模拟的可视化四、DeepMind神经网络建模五、图形编码六、图形处理器七、图形解码器八、具有不同弹簧常数的轨迹可视化九、预测的物理编码和推出轨迹 一、说明 这是一篇国外流体力学专家在可视化流体物理属性的设计…

如何使用vue脚手架创建项目

前言 使用vue搭建项目的时候&#xff0c;我们可以通过对应的cmd命令去打开脚手架&#xff0c;然后自己配置对应的功能插件 说明&#xff1a; 要使用Vue脚手架创建项目&#xff0c;你需要先确保你已经安装了Node.js和npm&#xff08;Node.js的包管理器&#xff09;。然后&#…

Github 2024-05-07 开源项目日报 Tp10

根据Github Trendings的统计,今日(2024-05-07统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量TypeScript项目4Jupyter Notebook项目2Python项目1Batchfile项目1非开发语言项目1Java项目1HTML项目1C#项目1从零开始构建你喜爱的技术 创建周期…

性能测试基础介绍

1.性能测试的意义 1.1.现状 互联网行业发展快&#xff0c;用户量大大增加&#xff1b; 业务和系统架构越来越复杂&#xff0c;数据越来越多&#xff0c;用户不仅仅满足于功能的实现&#xff0c;在某些场景下&#xff0c;更 在意系统性能。 1.2.什么是性能测试 通过一定的手段&…