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

3. Spring 更简单的读取和存储对象(五大类注解 方法注解)

目录

1. 存储 Bean 对象

1.1 配置扫描路径

1.2 添加注解存储 Bean 对象

1.2.1 @Controller(控制器存储)

1.2.2 @Service(服务存储)

1.2.3 @Repository(仓库存储)

1.2.4 @Component(组件存储)

1.2.5 @Configuration(配置存储)

1.3 使用多个类注解的原因

1.3.1 五大注解之间的关系

1.3.1 Bean 的命名规则

1.4 方法注解 @Bean

1.4.1 方法注解要配合类注解使用

1.4.2 重命名 Bean

1.4.3 给有参数的方法添加 Bean 注解 

1.4.4 Spring xml 配置的方式进行传参

2. 根据日志定位问题

NoSuchBeanDefinitionException -- 没有找到 Bean


在 Spring 中想要更简单的存储和读取对象的核心是使用注解。

1. 存储 Bean 对象

之前我们存储 Bean 时,需要在 spring-config 中添加⼀行 bean 注册内容才行,如下图所示:

但是现在我们可以通过注解来代替上面的配置。

1.1 配置扫描路径

想要将对象成功的存储到 Spring 中,我们需要配置⼀下存储对象的扫描包路径,只有被配置的包下的所有类,添加了注解才能被正确的识别并保存到 Spring 中

在 spring-config.xml 添加如下配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:content="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><content:component-scan base-package="com.bit.service"></content:component-scan>
</beans>

也就是说,即使添加了注解,如果不是在配置的扫描包下的类对象,也是不能被存储到 Spring 中的。

1.2 添加注解存储 Bean 对象

想要将对象存储在 Spring 中,有两种注解类型可以实现:

1. 类注解:@Controller、@Service、@Repository、@Component、@Configuration。

2. 方法注解:@Bean。

1.2.1 @Controller(控制器存储)

使用 @Controller 存储对象:

@Controller
public class UseController {public void sayHi(){System.out.println("hi,Controller...");}
}

接下来取对象:

public class App {public static void main(String[] args) {// 得到 Spring 上下文ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");// 获取 Bean 对象UserController user = (UserController) context.getBean("userController");// 使用 Beanuser.sayHi();}
}

可以发现在使用 getBean() 方法时,我们直接使用了注解下类名的小驼峰的形式,可以看到运行无误:

1.2.2 @Service(服务存储)

使用 @Service 存储对象:

@Service
public class UserService {public void sayHi(){System.out.println("Hi,Service...");}
}

 接下来取对象:

public class App {public static void main(String[] args) {// 得到 Spring 上下文ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");// 获取 Bean 对象UserService userService = (UserService)context.getBean("userService");// 使用 BeanuserService.sayHi();}
}
1.2.3 @Repository(仓库存储)

使用 @Repository 存储对象:

@Repository
public class UserRepository {public void sayHi(){System.out.println("Hi,Repository...");}
}

接下来取对象:

public class App {public static void main(String[] args) {// 得到 Spring 上下文ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");// 获取 Bean 对象UserRepository userRepository = (UserRepository)context.getBean("userRepository");// 使用 BeanuserRepository.sayHi();}
}
1.2.4 @Component(组件存储)

使用 @Component 存储对象:

@Component
public class UserComponent {public void sayHi(){System.out.println("Hi,Component...");}
}

 接下来取对象:

public class App {public static void main(String[] args) {// 得到 Spring 上下文ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");// 获取 Bean 对象UserComponent userComponent = (UserComponent)context.getBean("userComponent");// 使用 BeanuserComponent.sayHi();}
}
1.2.5 @Configuration(配置存储)

使用 @Configuration 存储对象: 

@Configuration
public class UserConfiguartion {public void sayHi(){System.out.println("Hi,Configuration...");}
}

 接下来取对象:

public class App {public static void main(String[] args) {// 得到 Spring 上下文ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");// 获取 Bean 对象UserConfiguartion userConfiguartion = (UserConfiguartion)context.getBean("userConfiguartion");// 使用 BeanuserConfiguartion.sayHi();}
}

1.3 使用多个类注解的原因

通过不同的类注解更加明确当前类的用途:

  • @Controller:表示的是业务逻辑层,控制器,通常是指程序的入口。比如参数校验、参数类型转换、前置处理工作等;
  • @Servie:服务层,一般写业务代码、服务编排、调用 DB、调用第三方接口等;
  • @Repository:持久层,仓库,通常是指 DB 操作相关的代码(Dao、mapper);
  • @Component:其他的对象;
  • @Configuration:配置层。
1.3.1 五大注解之间的关系

 查看 @Controller / @Service / @Repository / @Configuration 等注解的源码发现:

 这些注解里面都有⼀个注解 @Component,说明它们本身就是属于 @Component 的“子类”。

1.3.1 Bean 的命名规则

通过以上举例我们猜测:注解对应的 Bean 的名称是首字母小写。那么,真的如此吗?此时就需要我们去查看一下官方的文档。按住 CTRL + N 键进行搜索:

可以看到第四个是我们所需要的关于注解的,点进去后可以看到:

因此,我们得出结论:

当类名前两位均为大写时,需要返回自身类名;否则,返回首字母小写后的类名。

1.4 方法注解 @Bean

1.4.1 方法注解要配合类注解使用

类注解是添加到某个类上的,而方法注解是放到某个方法上的,如以下代码的实现:

public class Users {private String name;private Integer age;public String getName(){return name;}public void setName(String name){this.name = name;}public void setAge(Integer age){this.age = age;}
@Configuration
public class BeanConfig {@Beanpublic Users user(){Users user = new Users();user.setName("小明");user.setAge(18);return user;}public Users user2(){Users user = new Users();user.setName("小蓝");user.setAge(19);return user;}
}
public class App {public static void main(String[] args) {// 得到 Spring 上下文ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");// 获取 Bean 对象Users users = (Users) context.getBean("user");// 使用 BeanSystem.out.println(users.getName());}
}

@Bean 无法直接单独使用,必须搭配五大类注解使用。

Bean 对应生成的 Bean 名称是方法名。

1.4.2 重命名 Bean
@Configuration
public class BeanConfig {@Bean("aaa")public Users user(){Users user = new Users();user.setName("小明");user.setAge(18);return user;}public Users user2(){Users user = new Users();user.setName("小蓝");user.setAge(19);return user;}
}
@Configuration
public class BeanConfig {@Bean(name={"aaa","user"})public Users user(){Users user = new Users();user.setName("小明");user.setAge(18);return user;}public Users user2(){Users user = new Users();user.setName("小蓝");user.setAge(19);return user;}
}
@Configuration
public class BeanConfig {@Bean({"aaa","user"})public Users user(){Users user = new Users();user.setName("小明");user.setAge(18);return user;}public Users user2(){Users user = new Users();user.setName("小蓝");user.setAge(19);return user;}
}

以上三种方法均可实现 Bean 的重命名,重命名之后则无法使用原来的方法名来获取 Bean

 对五大类注解同样可以使用以上重命名的方法。

1.4.3 给有参数的方法添加 Bean 注解 
@Configuration
public class BeanConfig {@Bean({"aaa","user"})public Users user(Integer age){Users user = new Users();user.setName("小明");user.setAge(age);return user;}public Users user2(){Users user = new Users();user.setName("小蓝");user.setAge(19);return user;}
}

直接运行上述代码会报错,因为并没有找到 age 这个对象:

 此时修改代码如下:

@Configuration
public class BeanConfig {@Beanpublic Integer age(){return 15;}@Bean({"aaa","user"})public Users user(Integer age){Users user = new Users();user.setName("小明");user.setAge(age);return user;}public Users user2(){Users user = new Users();user.setName("小蓝");user.setAge(19);return user;}
}

 将对象交给 Spring 管理后,会自动匹配对应的类型,还可以通过其他方式去读取(比如配置文件中)。当只有一个 @Bean 注解时,根据类型进行匹配;当有多个 @Bean 时,根据名称进行匹配。

1.4.4 Spring xml 配置的方式进行传参
public class BeanConfig {public Users user(String name){Users user = new Users();user.setName(name);user.setAge(12);return user;}
}
<bean id="user" class="springcore"><constructor-arg name="name" value="小明"></constructor-arg>
</bean>

当需要注入的是对象时,要写引用:

public class UserController {private UserService userService;public UserController(UserService userService){this.userService = userService;}public void sayHi(){System.out.println("hi,Controller...");}
}
<bean id="user" class="springcore"><constructor-arg name="userService" ref="userService"></constructor-arg>
</bean>

2. 根据日志定位问题

NoSuchBeanDefinitionException -- 没有找到 Bean

Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'userController' available

 没有名为“userController”的bean可用。

可以看到此时是因为注解被注释了,不再生效的原因。

出现以上日志时还有另一种可能原因,如下图所示:

也就是说当我们的扫描路径与实际不符时,同样会出现找不到 Bean 的情况。

除了以上两种情况当我们通过注解获取 Bean 时,类名不符合要求同样会生成以上的日志,具体如下图所示:

还有一种情况是因为将注解重命名了,但是使用的依然时未重命名之前的注解,同样会生成以上日志:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.lang.Integer' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {} 

没有可用的“java.lang.Integer”类型的限定bean。

相关文章:

3. Spring 更简单的读取和存储对象(五大类注解 方法注解)

目录 1. 存储 Bean 对象 1.1 配置扫描路径 1.2 添加注解存储 Bean 对象 1.2.1 Controller&#xff08;控制器存储&#xff09; 1.2.2 Service&#xff08;服务存储&#xff09; 1.2.3 Repository&#xff08;仓库存储&#xff09; 1.2.4 Component&#xff08;组件存储&…...

TypeScript基础篇 - 泛型

目录 泛型的概念 接口是对方面的描述&#xff08;Aspect&#xff09;&#xff0c;继承其中几个方法。重定义方法 泛型是对共性的提取 泛型&#xff08;Generics&#xff09; 泛型的例子 泛型类 推荐写法 泛型约束 keyof操作符 泛型的特化&#xff08;实例化&#xff…...

C++ 常量

常量是固定值&#xff0c;在程序执行期间不会改变。这些固定的值&#xff0c;又叫做字面量。 常量可以是任何的基本数据类型&#xff0c;可分为整型数字、浮点数字、字符、字符串和布尔值。 常量就像是常规的变量&#xff0c;只不过常量的值在定义后不能进行修改。 整数常量…...

智安网络|实现数据安全:探索数据动态脱敏的落地策略

在当今数字化时代&#xff0c;数据安全成为企业和组织管理中的头等大事。然而&#xff0c;数据共享和数据大规模处理的需求也日益增长&#xff0c;这就需要在数据传输和存储过程中采取措施来保护用户的隐私。数据动态脱敏技术应运而生&#xff0c;为解决数据隐私和保护的问题提…...

全加器(多位)的实现

一&#xff0c;半加器 定义 半加器&#xff08;Half Adder&#xff09;是一种用于执行二进制数相加的简单逻辑电路。它可以将两个输入位的和&#xff08;Sum&#xff09;和进位&#xff08;Carry&#xff09;计算出来。 半加器有两个输入&#xff1a;A 和 B&#xff0c;分别代表…...

Clion开发stm32之微妙延迟(采用nop指令实现)

前言 需要借助逻辑分析仪动态调整参数此次测试的开发芯片为stm32f103vet6 延迟函数 声明 #define NOP_US_DELAY_MUL_CNT 5 /*nop 微妙延迟需要扩大的倍数(根据实际动态修改)*/ void bsp_us_delay_nop(uint32_t us);void bsp_ms_delay_nop(uint32_t ms);定义 void bsp_us_dela…...

Spring MVC -- 获取参数(普通对象+JSON对象+URL地址参数+文件+Cookie/Session/Header)

目录 1.获取参数 1.1获取单个参数 1.2获取多个参数 传参注意事项&#xff1a; 2.获取对象 3.后端参数重命名RequestParam 4.获取JSON对象RequestBody 5.从 URL 地址中获取参数 PathVariable 6.上传文件 RequestPart 7.获取Cookie/Session/Header 7.1 获取 Request 和…...

Langchain 的 Conversation summary memory

Langchain 的 Conversation summary memory 现在让我们看一下使用稍微复杂的内存类型 - ConversationSummaryMemory 。这种类型的记忆会随着时间的推移创建对话的摘要。这对于随着时间的推移压缩对话中的信息非常有用。对话摘要内存对发生的对话进行总结&#xff0c;并将当前摘…...

Safari 查看 http 请求

文章目录 1、开启 Safari 开发菜单2、显示 JavaScript 控制台 1、开启 Safari 开发菜单 Safari 设置中&#xff0c;打开开发菜单选项 *** 选择完成后&#xff0c;Safari 的目录栏就会出现一个 开发 功能。 2、显示 JavaScript 控制台 开启页面后&#xff0c;在开发中选中 显…...

kafka权限控制功能

参考链接&#xff1a; https://www.clougence.com/cc-doc/dataMigrationAndSync/database/privs_for_kafka Kafka需要的权限 | CloudCanal of ClouGence Kafka Topic 权限控制可以通过使用 Apache Kafka 的内置安全特性来实现。这主要涉及到两个方面&#xff1a;认证&#…...

公司内部重要文件如何加密防止泄露?

现如今&#xff0c;是互联网时代&#xff0c;数据安全在互联网时代中的数据安全岌岌可危&#xff0c;企业中&#xff0c;都会拥有终端&#xff0c;终端中每天都要处理文档&#xff0c;文件&#xff0c;表格&#xff0c;产生一系列的数据问题等&#xff0c;这个时候就要先企业中…...

C语言或Java-x型图案

描述 KiKi学习了循环&#xff0c;BoBo老师给他出了一系列打印图案的练习&#xff0c;该任务是打印用“*”组成的X形图案。 输入描述 多组输入&#xff0c;一个整数&#xff08;2~20&#xff09;&#xff0c;表示输出的行数&#xff0c;也表示组成“X”的反斜线和正斜线的长度。…...

FTP客户端登录报错:Login failed

FTP客户端登录报错&#xff1a;Login failed 是selinux的问题&#xff0c;一般用户无法登录用户主目录 [rootchenshuyi ~]# setsebool -P tftp_home_dir 1...

Linux相关指令(上)

常见指令&#xff1a; 1 pwd&#xff1a;查看用户当前所在目录 以下面的路径为例&#xff1a; 2 ls&#xff1a;对于目录&#xff0c;该命令列出该目录下的所有子目录与文件。 对于文件&#xff0c;将列出文件名以及其他信息 ls-l&#xff08;or ll&#xff09;&#xff1a;列…...

电压放大器在管道缺陷检测中应用有哪些

管道是一种重要的输送工业介质的设施&#xff0c;广泛应用于石油、化工、水利等领域。然而&#xff0c;由于长期使用和外界环境因素等原因&#xff0c;管道内部常会出现各种缺陷和损伤&#xff0c;如腐蚀、裂纹、磨损等&#xff0c;这些问题如果得不到及时发现和修复&#xff0…...

NLP(六十二)HuggingFace中的Datasets使用

Datasets库是HuggingFace生态系统中一个重要的数据集库&#xff0c;可用于轻松地访问和共享数据集&#xff0c;这些数据集是关于音频、计算机视觉、以及自然语言处理等领域。Datasets 库可以通过一行来加载一个数据集&#xff0c;并且可以使用 Hugging Face 强大的数据处理方法…...

Windows下基于VSCode搭建C++开发环境(包含整合MinGW64、CMake的详细流程)

最近想写写C&#xff0c;装了VisualStudio 2022&#xff0c;折腾半天。对于一个用惯VSCode的人来说&#xff0c;总感觉IDE太笨重。于是自己网上各种查资料&#xff0c;自己琢磨&#xff0c;搭建了一套Windows下基于VSCode和CMake的C轻量级开发环境。 具体搭建步骤 1. 下载并安…...

springboot+mybatis-plus+vue+element+vant2实现短视频网站,模拟西瓜视频移动端

目录 一、前言 二、管理后台 1.登录 2.登录成功&#xff0c;进入欢迎页 ​编辑 3.视频分类管理 4. 视频标签管理 5.视频管理 6.评论管理 ​编辑 7.用户管理 8.字典管理 &#xff08;类似于后端的枚举&#xff09; 9.参数管理&#xff08;富文本录入&#xff09; 10.管…...

MySQL学习-第二部分

文章目录 MySQL数据库学习1 表1.1 表中的数据类型1.2 表的创建1.3 表的删除1.4 default设置字段默认值1.5 表结构的修改1.5.1 表名的修改1.5.2 字段名的修改1.5.3 修改字段类型1.5.4 添加字段1.5.5 删除字段1.5.6 表的复制 1.6 表的约束1.6.1 什么是约束&#xff1f;1.6.2 not …...

TortoiseGit 入门指南17:使用子模块

如果你想在自己的代码仓库中嵌入其它仓库&#xff0c;这称为引入子模块&#xff08;Submodule&#xff09;。使用右键菜单TortoiseGit - Submodules Add 选项&#xff0c;弹出添加子模块对话框&#xff0c;可以将一个外部仓库嵌入到源代码树的专用子目录中。 Repository&#x…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...