当前位置: 首页 > news >正文

[Spring] @Bean 修饰方法时如何注入参数

目录

一、@Bean 的简单使用

1、正常情况

2、问题提出

二、解决方案

1、@Qualifier

2、直接写方法名

三、特殊情况

1、DataSource


一、@Bean 的简单使用

在开发中,基于 XML 文件配置 Bean 对象的做法非常繁琐且不好维护,因此绝大部分情况下都是使用“完全注解开发”。

对于 Spring 而言,IOC 容器中的 Bean 对象的创建和使用是一大重点,Spring 也为我们提供了注解方式创建 bean 对象:使用 @Bean。

在举例之前,先熟悉以下两个需要用到的类:

(1)User 类

package com.demo.pojo;import org.springframework.stereotype.Component;@Component
public class User {private String name;public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +'}';}
}

 (2)Book 类

package com.demo.pojo;import org.springframework.stereotype.Component;@Component
public class Book {private User user;public void setUser(User user) {this.user = user;}public User getUser() {return user;}
}

1、正常情况

(1)下面是一个简单的 bean 对象创建:

@Bean
public User getUser() {return new User();
}

经此操作,IOC 中就会多出一个与 <bean id = "getUser" class = "类路径.User"/> 同义的 bean 对象。即:方法名就是 id,返回类型就是 class

(2)含有普通类型参数的 bean 对象创建:

@Bean
public User getUser(@Value("wyt") String name) {User user = new User();user.setName(name);return user;
}

需要注意的是,方法中的参数并不是 bean 对象的成员属性,而是代表着 bean 对象的创建依赖于这几个参数,或许用来 setParameter,或许只是中间变量。

而在 xml 文件中的 <property> 则必须要求用 set 方法。

(3)含有对象类型参数的 bean 对象创建:

package com.demo.config;import com.demo.pojo.Book;
import com.demo.pojo.User;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;@Configuration
public class Config {@Beanpublic User getUser(@Value("wyt") String name) {User user = new User();user.setName(name);return user;}@Beanpublic Book createBook(User user) {Book book = new Book();book.setUser(user);return book;}
}

对比在 xml 中是如何实现参数是对象类型时的属性注入:

(4)正常情况下,@Bean 使用总结

(4-1)@Bean 注解的方法,其返回值就是一个 <bean> 对象,并且注册到了 IOC 容器中。

  • id 为方法的名字;
  • class 为方法的返回类型;

(4-2)@Bean 对象的实例化依赖于方法内的参数,参数可以是普通类型,也可以是对象类型。

  • 若为普通类型,用 @Value("xxx") 来注入这个参数;
  • 若为对象类型,则默认情况下,Spring 会到 IOC 容器中寻找与参数类型相同的 bean 对象来注入这个参数;

2、问题提出

根据上述内容,我们会想到:如果参数是对象类型,可是 IOC 中拥有不止一个相同类型的 bean 对象,这该怎么办呢?

比如下面的情况:

可以看到,Book 对象的参数 user 已经报错了,无法自动装配,因为存在多个 User 类型的 Bean,Spring 不知道应该将哪个 bean 注入到 user 中

二、解决方案

首先我们要知道,默认情况下,参数的注入使用的是 @Autowired,不需要显式写出。

1、@Qualifier

我们可以想到,@Autowired 是根据类型自动装配,当一个类型有多个 bean 对象时失效。

而 @Qualifier 是根据名称进行装配,这不就意味着我们可以用 @Qualifier 来明确需要的 bean 对象嘛。

这有两种写法,都是有效的:

  • 直接在参数前加 @Qualifier("function_name");
  • 在方法前加 @Qualifier("function_别名"),在参数前加 @Qualifier("function_别名");

(1)配置类

package com.demo.config;import com.demo.pojo.Book;
import com.demo.pojo.User;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;@Configuration
public class Config {@Beanpublic User getUser(@Value("wyt") String name) {User user = new User();user.setName(name);return user;}@Beanpublic User createUser(@Value("wyt") String name) {User user = new User();user.setName(name);return user;}@Beanpublic Book createBook(@Qualifier("createUser") User user) {Book book = new Book();book.setUser(user);return book;}
}

(2)测试代码

@Test
public void SameObjectTest() {ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);Book book = context.getBean("createBook", Book.class);System.out.println(book.getUser());
}

(3)输出结果

2、直接写方法名

因为一般情况下,方法名不能相同,因此也可以通过将参数名写成对应的方法名来进行注入

package com.demo.config;import com.demo.pojo.Book;
import com.demo.pojo.User;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;@Configuration
public class Config {@Beanpublic User getUser(@Value("wyt") String name) {User user = new User();user.setName(name);return user;}@Beanpublic User createUser(@Value("wyt") String name) {User user = new User();user.setName(name);return user;}@Beanpublic Book createBook(User createUser) {Book book = new Book();book.setUser(createUser);return book;}
}

三、特殊情况

在这里要说明一些特别的对象类型,比如:DataSource。

1、DataSource

(1)问题描述

@Bean
public DruidDataSource createDruidDataSource() {DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName(driver);dataSource.setUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);return dataSource;
}@Bean
public DruidDataSource getDruidDataSource() {DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName(driver);dataSource.setUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);return dataSource;
}

当我们像上面的代码一样,写了两个数据源的 bean 对象之后,运行就会出现如下报错: 

No qualifying bean of type 'javax.sql.DataSource' available: expected single matching bean but found 2

简单来说,就是因为 Spring 有其自身的配置类,导致程序不知道选择哪一个数据源。

(2)解决方法

给其中任意一个加上 @Primary,代表当出现多个同类型 bean 时,优先使用哪一个。写上之后,就可以使用前文所述的方法,如:@Qualifier 或直接写方法名。

@Bean
@Primary
public DruidDataSource createDruidDataSource() {DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName(driver);dataSource.setUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);return dataSource;
}

相关文章:

[Spring] @Bean 修饰方法时如何注入参数

目录 一、Bean 的简单使用 1、正常情况 2、问题提出 二、解决方案 1、Qualifier 2、直接写方法名 三、特殊情况 1、DataSource 一、Bean 的简单使用 在开发中&#xff0c;基于 XML 文件配置 Bean 对象的做法非常繁琐且不好维护&#xff0c;因此绝大部分情况下都是使用…...

docker拉取镜像错误 missing signature key

您正在尝试使用 yum 在 CentOS 或 RHEL 系统上安装 docker-ce&#xff0c;但您遇到了一些问题。根据您提供的输出&#xff0c;这里有几个需要注意的点&#xff1a; 系统未注册: "This system is not registered with an entitlement server" 指示您的系统未注册。对于…...

基于可解释性特征矩阵与稀疏采样全局特征组合的人体行为识别

论文还未发表&#xff0c;不细说&#xff0c;欢迎讨论。 Title: A New Solution to Skeleton-Based Human Action Recognition via the combination usage of explainable feature extraction and sparse sampling global features. Abstract: With the development of deep …...

OpenCV4(C++)—— 仿射变换、透射变换和极坐标变换

文章目录 一、仿射变换1. getRotationMatrix2D()2. warpAffine() 二、透射变换三、极坐标变换 一、仿射变换 在OpenCV中没有专门用于图像旋转的函数&#xff0c;而是通过图像的仿射变换实现图像的旋转。实现图像的旋转首先需要确定旋转角度和旋转中心&#xff0c;之后确定旋转…...

http.header.Set()与Add()区别;

在Go语言中进行HTTP请求时&#xff0c;http.Header对象表示HTTP请求或响应的头部信息。http.Header是一个map[string][]string类型的结构&#xff0c;用于存储键值对&#xff0c;其中键表示HTTP头字段的名称&#xff0c;值是一个字符串切片&#xff0c;可以存储多个相同名称的头…...

vue-7-vuex

一、Vuex 概述 目标&#xff1a;明确Vuex是什么&#xff0c;应用场景以及优势 1.是什么 Vuex 是一个 Vue 的 状态管理工具&#xff0c;状态就是数据。 大白话&#xff1a;Vuex 是一个插件&#xff0c;可以帮我们管理 Vue 通用的数据 (多组件共享的数据)。例如&#xff1a;购…...

SSO单点登录和OAuth2.0区别

一、概述 SSO是Single Sign On的缩写&#xff0c;OAuth是Open Authority的缩写&#xff0c;这两者都是使用令牌的方式来代替用户密码访问应用。流程上来说他们非常相似&#xff0c;但概念上又十分不同。SSO大家应该比较熟悉&#xff0c;它将登录认证和业务系统分离&#xff0c…...

【轻松玩转MacOS】基本操作篇

引言 本文是系列的开篇&#xff0c;我将为大家介绍MacOS的基本操作。对于初次接触MacOS的用户来说&#xff0c;掌握这些基本操作是必不可少的。无论是启动和关机&#xff0c;还是使用键盘和鼠标&#xff0c;或者是快捷键的使用&#xff0c;这些基本操作都是你开始使用MacOS的第…...

华为ICT——第三章图像处理基本任务

目录 1&#xff1a;数字图像处理的层次&#xff1a;&#xff08;处理-分析-理解&#xff09;顺序不能错&#xff1a; 2&#xff1a;图像处理&#xff08;图像处理过程&#xff09;&#xff1a; 3&#xff1a;图像分析&#xff08;特征提取&#xff09;&#xff1a; 4&#x…...

(C++)引用的用法总结

引用&#xff08;reference&#xff09;是C极为重要的一部分&#xff0c;本文对其用法进行简单总结。 1. 引用的基本用法 引用的关键字为&&#xff0c;表示取地址的意思&#xff0c;引用变量定义如下&#xff1a; int m 1; int &n m; //定义 cout<<"n:…...

Charles:移动端抓包 / windows客户端 iOS手机 / 手机访问PC本地项目做调试

一、背景描述 1.1、本文需求&#xff1a;移动端进行抓包调试 1.2、理解Charles可以做什么 Charles是一款跨平台的网络代理软件&#xff0c;可以用于捕获和分析网络流量&#xff0c;对HTTP、HTTPS、HTTP/2等协议进行调试和监控。使用Charles可以帮助开发人员进行Web开发、调试…...

【AI】深度学习——人工智能、深度学习与神经网络

文章目录 0.1 如何开发一个AI系统0.2 表示学习(特征处理)0.2.1 传统特征学习特征选择过滤式包裹式 L 1 L_1 L1​ 正则化 特征抽取监督的特征学习无监督的特征学习 特征工程作用 0.2.2 语义鸿沟0.2.3 表示方式关联 0.2.4 表示学习对比 0.3 深度学习0.3.1 表示学习与深度学习0.3.…...

RK3288:BT656 RN6752调试

这篇文章主要想介绍一下再RK3288平台上面调试BT656 video in的注意事项。以RN6752转接芯片&#xff0c;android10平台为例进行介绍。 目录 1. RK3288 VIDEO INPUT 并口 2. 驱动调试 2.1 RN6752 驱动实现 ①rn6752_g_mbus_config总线相关配置 ②rn6752_querystd配置制式 …...

LLMs 蒸馏, 量化精度, 剪枝 模型优化以用于部署 Model optimizations for deployment

现在&#xff0c;您已经了解了如何调整和对齐大型语言模型以适应您的任务&#xff0c;让我们讨论一下将模型集成到应用程序中需要考虑的事项。 在这个阶段有许多重要的问题需要问。第一组问题与您的LLM在部署中的功能有关。您需要模型生成完成的速度有多快&#xff1f;您有多…...

Milvus踩坑笔记

本文用于记录在学习 Milvus文档时所遇到的一些Bug或报错及解决方法 参考文章&#xff1a; 官方demo&#xff1a;在Dynamic Schema的集合中插入数据 报错1&#xff1a;auto id enabled, id shouldnt in entities[0] 问题描述 此报错出现在Milvus官方在介绍 Dynamic Schema …...

什么是轴电流?轴电流对轴承有什么危害?

根据同步发电机结构及工作原理&#xff0c;由于定子铁芯组合缝、定子硅钢片接缝&#xff0c;定子与转子空气间隙不均匀&#xff0c;轴中心与磁场中心不一致等&#xff0c;机组的主轴不可避免地要在一个不完全对称的磁场中旋转。这样&#xff0c;在轴两端就会产生一个交流电压。…...

react create-react-app v5配置 px2rem (不暴露 eject方式)

环境信息&#xff1a; create-react-app v5 “react”: “^18.2.0” “postcss-plugin-px2rem”: “^0.8.1” 配置步骤&#xff1a; 不暴露 eject 配置自己的webpack&#xff1a; 1.下载react-app-rewired 和 customize-cra-5 npm install react-app-rewired customize-cra…...

.net中用标志位解决socket粘包问题

以下为wpf中, 用标志位"q" 解决粘包问题 using MyFrameWorkWpf.Entities; using System.Collections.ObjectModel; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.…...

【Ubuntu】Systemctl 管理 MinIO 服务器的启动和停止

要使用 systemctl 来管理 MinIO 服务器的启动和停止&#xff0c;您需要创建一个 systemd 服务单元文件&#xff0c;以便 systemd 能够启动和停止 MinIO 服务器。下面是一般的步骤&#xff1a; 创建 systemd 服务单元文件&#xff1a; 打开终端并使用文本编辑器创建一个新的 sys…...

《golang设计模式》第二部分·结构型模式-07-代理模式(Proxy)

文章目录 1. 概述1.1 角色1.2 模式类图 2. 代码示例2.1 设计2.2 代码2.3 示例类图 1. 概述 代理&#xff08;Proxy&#xff09;是用于控制客户端访问目标对象的占位对象。 需求&#xff1a;在调用接口实现真是主题之前需要一些提前处理。 解决&#xff1a;写一个代理&#xff…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码&#xff0c;而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库&#xff0c;可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画&#xff0c;可以包含在你的网页或应用项目中。 3.An…...

代码规范和架构【立芯理论一】(2025.06.08)

1、代码规范的目标 代码简洁精炼、美观&#xff0c;可持续性好高效率高复用&#xff0c;可移植性好高内聚&#xff0c;低耦合没有冗余规范性&#xff0c;代码有规可循&#xff0c;可以看出自己当时的思考过程特殊排版&#xff0c;特殊语法&#xff0c;特殊指令&#xff0c;必须…...

适应性Java用于现代 API:REST、GraphQL 和事件驱动

在快速发展的软件开发领域&#xff0c;REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名&#xff0c;不断适应这些现代范式的需求。随着不断发展的生态系统&#xff0c;Java 在现代 API 方…...

tomcat指定使用的jdk版本

说明 有时候需要对tomcat配置指定的jdk版本号&#xff0c;此时&#xff0c;我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...

c# 局部函数 定义、功能与示例

C# 局部函数&#xff1a;定义、功能与示例 1. 定义与功能 局部函数&#xff08;Local Function&#xff09;是嵌套在另一个方法内部的私有方法&#xff0c;仅在包含它的方法内可见。 • 作用&#xff1a;封装仅用于当前方法的逻辑&#xff0c;避免污染类作用域&#xff0c;提升…...

在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7

在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤&#xff1a; 第一步&#xff1a; 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为&#xff1a; // 改为 v…...

OCR MLLM Evaluation

为什么需要评测体系&#xff1f;——背景与矛盾 ​​ 能干的事&#xff1a;​​ 看清楚发票、身份证上的字&#xff08;准确率>90%&#xff09;&#xff0c;速度飞快&#xff08;眨眼间完成&#xff09;。​​干不了的事&#xff1a;​​ 碰到复杂表格&#xff08;合并单元…...