Spring中@Bean标注的方法是如何创建对象呢?

news/2025/2/22 5:50:54/

@Bean 标注的方法如何创建对象呢?

参考文章:https://blog.csdn.net/qq_35971258/article/details/128241353

下边只讲一下 @Bean 注解标注的方法,是如何去进行创建 bean,以及流程是怎样的,如果需要看源码具体执行流程,可以查看上边参考文章

Spring 的 @Bean 标注的方法会被创建成 Bean,这个创建的过程在源码中是怎么执行的呢?

@Configuration
public class MyConfiguration {@Beanpublic Blue blue() {System.out.println("创建 Blue 对象");return new Blue();}}

当使用上述代码时,在 Spring 中扫描到 MyConfiguration 类时,会发现 MyConfiguration 的 BeanDefinition 包含了 FactoryMethod,也就是 Spring 为带有 @Bean 注解的方法创建了一个 FactoryMethod,这个 FactoryMethod 也就是 blue() 方法,最后通过执行 FactoryMethodblue() 就可以创建出 Blue 对象,再将 Blue 对象交给 Spring 进行管理,最后创建的 Blue 对象的 beanName 就是 @Bean 标注的方法名

总结一下:@Bean 标注的方法会是一个 FactoryMethod,最后通过执行这个 FactoryMethod 来创建 Bean 对象,beanName 为方法名 {beanName: blud, }

Spring 的 @Bean 标注的方法的参数如何注入的呢?

@Configuration
public class MyConfiguration {@Beanpublic Blue blue(White white) {System.out.println("创建 Blue 对象");System.out.println("获取了 White 对象:" + white);return new Blue();}@Beanpublic White white() {White white = new White();System.out.println("创建的 White 对象:" + white);return white;}/*** 输出:* 创建的 White 对象:com.zqy.springbean.SpringBean.beans.White@32c726ee* 创建 Blue 对象* 获取了 White 对象:com.zqy.springbean.SpringBean.beans.White@32c726ee*/
}

参数注入流程为:

  1. 对上边的 @Bean 方法来说,如果方法存在参数,会先根据参数名到 Spring 容器中取出对应的 bean,即先根据 white 取出对应的 bean
  2. 如果根据 white 没有取到对应的 bean,就会根据对象的类型去取,如果 Spring 容器中,White 类型的 Bean 只有 1 个,就会取出来进行赋值
  3. 但是如果 Spring 容器中 White 类型的 Bean 有多个时,Spring 内部就会进行决策判断,通过决策判断出来需要使用哪个 Bean 进行赋值,如果没有决策成功,Spring 就会报错 Parameter 0 of method blue in com.zqy.springbean.SpringBean.MyConfiguration required a single bean, but 2 were found:,即 Spring 根据类型找到了多个 Bean,但是并不知道使用哪一个!

这个决策过程为:

  1. 如果 Spring 找到多个同类型的 Bean,会查看是否有 Bean 标注了 @Primary 注解,如果有,就使用该 Bean 进行赋值
  2. 如果没有标注 @Primary,则会判断这几个 Bean 是否实现了 @Comparator 排序接口,如果有,就使用该 Bean
  3. 如果都没有找到,再根据入参名称和 beanName 进行比较,如果相同就使用该 Bean,否则报错

下面我们对这几种情况进行代码演示:

  1. 根据 beanName 找到入参

    会发现根据 beanName 成功找到 bean 对象,赋值给 blue() 方法的入参

    @Configuration
    public class MyConfiguration {@Beanpublic Blue blue(White white1) {System.out.println("获取了 White 对象:" + white1);return new Blue();}@Beanpublic White white1() {White white = new White();System.out.println("创建的 White1 对象:" + white);return white;}/*** 输出:创建的 White1 对象:com.zqy.springbean.SpringBean.beans.White@2c07545f获取了 White 对象:com.zqy.springbean.SpringBean.beans.White@2c07545f*/
    }
    
  2. 如果有多个同类型的 bean,根据 @Primary 找到 Bean 进行赋值

    可以发现,入参注入的 bean 对象为携带了 @Primary 注解的 bean

    @Configuration
    public class MyConfiguration {@Beanpublic Blue blue(White white) {System.out.println("获取了 White 对象:" + white);return new Blue();}@Bean@Primarypublic White white1() {White white = new White();System.out.println("创建的 White1 对象,携带 @Primary 注解:" + white);return white;}@Beanpublic White white2() {White white = new White();System.out.println("创建的 White2 对象:" + white);return white;}/*** 输出:创建的 White1 对象,携带 @Primary 注解:com.zqy.springbean.SpringBean.beans.White@2c4d1ac获取了 White 对象:com.zqy.springbean.SpringBean.beans.White@2c4d1ac创建的 White2 对象:com.zqy.springbean.SpringBean.beans.White@7f0d96f2*/
    }
    
  3. 有多个同类型的 bean,根据入参名beanName比较进行赋值

    可以发现,入参名为 white1 ,White 类型的 bean 有两个,beanName 分别为 white1white2,根据比较,入参使用 white1 的 bean

    @Configuration
    public class MyConfiguration {@Beanpublic Blue blue(White white1) {System.out.println("获取了 White 对象:" + white1);return new Blue();}@Beanpublic White white1() {White white = new White();System.out.println("创建的 White1 对象:" + white);return white;}@Beanpublic White white2() {White white = new White();System.out.println("创建的 White2 对象:" + white);return white;}/*** 输出:创建的 White1 对象:com.zqy.springbean.SpringBean.beans.White@2c07545f获取了 White 对象:com.zqy.springbean.SpringBean.beans.White@2c07545f创建的 White2 对象:com.zqy.springbean.SpringBean.beans.White@e57b96d*/
    }
    


http://www.ppmy.cn/news/1201799.html

相关文章

ZZ308 物联网应用与服务赛题第B套

2023年全国职业院校技能大赛 中职组 物联网应用与服务 任 务 书 (B卷) 赛位号:______________ 竞赛须知 一、注意事项 1.检查硬件设备、电脑设备是否正常。检查竞赛所需的各项设备、软件和竞赛材料等; 2.竞赛任务中所使用的…

第十八章 ObjectScript 应用程序中的数值计算

文章目录 第十八章 ObjectScript 应用程序中的数值计算 介绍SQL 表示 十进制格式$DOUBLE 格式 第十八章 ObjectScript 应用程序中的数值计算 介绍 IRIS 有两种不同的数字表示方式: 其中第一个根源于 IRIS 的原始实现。这种表示形式将被称为十进制格式。 在类定义中…

将json数据导入到ES集群——解决方案对比填坑日记

需求 将写好的json数据。导入到es集群 数据说明 文件JSON数据,一行一个JSON。 {"id":"d2716ae8fba4e026c4bd9445c3f49e2c","lang":"zh","title":"吉美旅馆","content":"吉美..."}…

论文阅读——What Can Human Sketches Do for Object Detection?(cvpr2023)

论文:https://openaccess.thecvf.com/content/CVPR2023/papers/Chowdhury_What_Can_Human_Sketches_Do_for_Object_Detection_CVPR_2023_paper.pdf 代码:What Can Human Sketches Do for Object Detection? (pinakinathc.me) 一、 Baseline SBIR Fram…

必看!2023年最新MSP开源应用程序指南电子书大揭秘

开源工具有利于节省成本、更好的技术和灵活性已经成为业界的共识。 在理想的世界中,我们用于工作的一切都可以是基于开源的。 但是在生产关键服务的实施和管理中,工程师和业务决策者必须有更好的决策方法来确定哪些工具可以适用于每个需求。 这并不表示…

Python 中的真与假

在 Python 这门编程语言中,真值与假值的概念起着至关重要的作用,它们决定了Python如何判断一个表达式是真还是假,这在涉及变量条件的情况下尤为重要。在本文中,我们将深入探讨Python如何进行真值和假值的评估,以及如何…

CSS中calc(80vw - 100px)为什么不加空格会不生效?

问题起因 今天再使用calc时发现无法生效,我的写法是: width: calc(100%-100px);页面无效果,加空格后就发现有效果了: width: calc(100% - 100px);有亿点疑惑,这是为什么? calc是什么? css3的…

html界面释放

2种方法 1、使用scale <div style"transform: scale(0.70);transform-origin: 0px 0px;width: 143%;"> 2、首页zoom <div style"zoom:0.725;">