Spring的常用注解之@Component——day1

1、@Component

@Component:泛指各种组件;它允许 Spring 自动检测自定义 Bean。换句话说,无需编写任何明确的代码,Spring 就能做到:

  • 扫描应用,查找注解为 @Component 的类
  • 将它们实例化,并注入任何指定的依赖
  • 在需要的地方注入

不过,大多数时候应该使用更专业的元(Stereotype)注解来实现这一功能。

2、Spring元注解

Spring 提供了一些专门的元注解:@Controller@Service 和 @Repository。它们都提供了与 @Component 相同的功能。都可以称为@Component。它们的作用都是一样的,因为它们都是由 @Component 作为元注解组成的注解。它们就像 @Component 别名,在 Spring 自动检测或依赖注入之外有专门的用途和意义。理论上,如果愿意,可以只使用 @Component 来满足我们对 Bean 自动检测的需求。反过来,也可以编写使用 @Component 的专用注解。

不过,Spring 的其他领域会专门使用 Spring 的专用注解来提供额外的自动化优势。因此,应该在大多数情况下坚持使用预定义的专用注解。

@Controller:控制层

@Service:业务层

@Repository:数据访问层

假设在 Spring Boot 项目中拥有上述每种情况的示例:

@Controller
public class ControllerExample {
}@Service
public class ServiceExample {
}@Repository
public class RepositoryExample {
}@Component
public class ComponentExample {
}@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface CustomComponent {
}@CustomComponent
public class CustomComponentExample {
}

可以编写一个测试,证明 Spring 能自动检测到每个 Bean 并将其添加到 ApplicationContext 中:

@SpringBootTest
@ExtendWith(SpringExtension.class)
public class ComponentUnitTest {@Autowiredprivate ApplicationContext applicationContext;@Testpublic void givenInScopeComponents_whenSearchingInApplicationContext_thenFindThem() {assertNotNull(applicationContext.getBean(ControllerExample.class));assertNotNull(applicationContext.getBean(ServiceExample.class));assertNotNull(applicationContext.getBean(RepositoryExample.class));assertNotNull(applicationContext.getBean(ComponentExample.class));assertNotNull(applicationContext.getBean(CustomComponentExample.class));}
}

3、@ComponentScan

@Component 只是一个普通的注解。该注解的作用是将 Bean 与其他对象(如 Domain 对象)区分开来。

Spring 使用 @ComponentScan 注解将它们收集到 ApplicationContext 中。

Spring Boot 中的 @SpringBootApplication 注解就是一个包含了 @ComponentScan 的注解。只要 @SpringBootApplication 类位于项目根目录,它就会默认扫描应用中定义的每个 @Component

如果 @SpringBootApplication 类不在项目根目录下,或者想扫描外部资源,可以显式配置 @ComponentScan 来查找指定的任何包,只要它存在于 classpath 上。

定义一个超出扫描范围的 @Component Bean:

package com.baeldung.component.scannedscope;@Component
public class ScannedScopeExample {
}

接着,通过 @ComponentScan 注解指定其所在的包:

package com.baeldung.component.inscope;@SpringBootApplication
@ComponentScan({"com.baeldung.component.inscope", "com.baeldung.component.scannedscope"})
public class ComponentApplication {//public static void main(String[] args) {...}
}

最后,可以测试一下它是别成功扫描加载到:

@Test
public void givenScannedScopeComponent_whenSearchingInApplicationContext_thenFindIt() {assertNotNull(applicationContext.getBean(ScannedScopeExample.class));
}

当要扫描项目中的外部依赖时,这种情况更有可能发生。

4、@Component 的限制

在某些情况下,无法使用 @Component。但仍希望指定对象成为 Spring 管理的 Bean。

在项目外的包中定义一个使用 @Component 注解的对象:

package com.baeldung.component.outsidescope;@Component
public class OutsideScopeExample {
}

下面的测试可以证明 ApplicationContext 不包含外部包中定义的组件:

@Test
public void givenOutsideScopeComponent_whenSearchingInApplicationContext_thenFail() {assertThrows(NoSuchBeanDefinitionException.class, () -> applicationContext.getBean(OutsideScopeExample.class));
}

另外,因为它来自第三方,可能无法编辑源码,无法添加 @Component 注解。又或者,我们想根据运行环境有条件地使用一种 Bean 实现,而不是另一种。自动检测通常就足够了,但当它无法满足需求时,可以使用 @Bean 注解。

5、@Component 和 @Bean

@Bean 也是 Spring 用于在运行时收集 Bean 的注解,但它不是用在类级别上的。相反,使用 @Bean 注解方法,以便 Spring 可以将方法的结果存储为 Spring Bean。

首先,创建一个没有注解的 POJO:

public class BeanExample {
}

在 @Configuration 注解的配置类中,可以创建一个生成 Bean 的方法:

@Bean
public BeanExample beanExample() {return new BeanExample();
}

BeanExample 可能代表一个本地类,也可能是一个外部类。这并不重要,只需要返回它的一个实例即可。

然后,编写一个测试,验证 Spring 是否加载了 Bean:

@Test
public void givenBeanComponents_whenSearchingInApplicationContext_thenFindThem() {assertNotNull(applicationContext.getBean(BeanExample.class));
}

由于 @Component 和 @Bean 之间的差异,应该注意一些重要的影响。

  • @Component 是一个类级别的注解,而 @Bean 是方法级别的注解,因此只有在类的源代码可编辑时,才可以使用 @Component 作为选项。@Bean 始终可以使用,但它的语法更加冗长。
  • @Component 与 Spring 的自动检测兼容,但 @Bean 需要手动实例化类。
  • 使用 @Bean 可以将 Bean 的实例化与其类定义分离。因此,可以使用它将第三方类转化为 Spring Bean。这也意味着可以添加逻辑来决定要使用哪个实例作为 Bean。

6、总结

本文介绍了 Spring @Component 注解和其他相关主题。

各种 Spring 元注解,只是 @Component 的专门版本。

@Component 注解的组件依需要被 @ComponentScan 扫描才能被实例化为 Spring Bean。

如果不能编辑源码,没法给组件类添加 @Component 注解,那么可以自定义配置类,在方法上使用 @Bean 注解手动地初始化组件类为 Spring Bean。

 

转载自:https://springdoc.cn/spring-component-annotation/

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

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

相关文章

【OpenGL】vs中glsl高亮显示插件

vs中glsl高亮显示插件 扩展搜索glsl安装

<项目代码>YOLOv8 猫狗识别<目标检测>

YOLOv8是一种单阶段(one-stage)检测算法,它将目标检测问题转化为一个回归问题,能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法(如Faster R-CNN),YOLOv8具有更高的…

jmeter脚本-请求体设置变量and请求体太长的处理

目录 1、查询接口 1.1 准备组织列表的TXT文件,如下: 1.2 添加 CSV数据文件设置 ,如下: 1.3 接口请求体设置变量,如下: 2、创建接口 2.1 见1.1 2.2 见1.2 2.3 准备创建接口的请求体TXT文件&#xff…

哔哩哔哩车机版2.7.0|专为司机打造的车机版B站,内容丰富,功能齐全

哔哩哔哩车机版是一款专为司机朋友们打造的车机版应用,扫码登录即可使用。该软件让你通过耳朵了解最新的游戏、动画动漫信息,感受其独特的趣味性内容。车机版亮点包括二次元和三次元的鬼畜视频、原创和翻唱音乐、前沿科技科普、国内外优秀舞蹈作品等。软…

在Mac下安装时间序列软件Hector

1.软件介绍 Hector 是一款开源软件,专用于 GNSS 时间序列数据的处理与分析,广泛应用于地球科学研究。它帮助研究人员从 GNSS 数据中提取长期趋势、周期性成分,并建模噪声特性,用于地壳形变、地震影响和气候变化等方面的研究。Hec…

opencv python笔记

OpenCV课程 OpenCV其实就是一堆C和C语言的源代码文件,这些源代码文件中实现了许多常用的计算机视觉算法。 OpenCV的全称是Open Source Computer Vision Library,是一个开放源代码的计算机视觉库OpenCV最初由英特尔公司发起并开发,以BSD许可证授权发行,可以在商业和研究领域中…

Rust 力扣 - 2461. 长度为 K 子数组中的最大和

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 我们遍历长度为k的窗口,用一个哈希表记录窗口内的所有元素(用来对窗口内元素去重),我们取哈希表中元素数量等于k的窗口总和的最大值 题解代码 use std::collecti…

[实战-11] FlinkSql 设置时区对TIMESTAMP和TIMESTAMP_LTZ的影响

table.local-time-zone table.local-time-zoneDataStream-to-Table Conversion(拓展知识)代码测试flinksql代码执行结果截图1. Asia/Shanghai 结果如下2. UTC结果如下 table.local-time-zone table.local-time-zone可用于设置flinksql的时区。 flink的内…

rnn/lstm 项目实战

tip:本项目用到的数据和代码在https://pan.baidu.com/s/1Cw6OSSWJevSv7T1ouk4B6Q?pwdz6w2 1. RNN : 预测股价 任务:基于zgpa_train.csv数据,建立RNN模型,预测股价 1.完成数据预处理,将序列数据转化为可用于RNN输入的数据 2.对新数据zgpa_test.csv进…

MySQL超大分页怎么优化处理?limit 1000000,10 和 limit 10区别?覆盖索引、面试题

1. limit 100000,10 和 limit 10区别 LIMIT 100000, 10: 这个语句的意思是,从查询结果中跳过前100000条记录,然后返回接下来的10条记录。这通常用于分页查询中,当你需要跳过大量的记录以获取后续的记录时。例如,如果你…

规范:项目、目录、文件、样式、事件、变量、方法、url参数、注释、git提交 命名规范及考证

一、规范命名的重要性 易懂、通用、规范、标准、专业性、是经验积累的体现 1.1、常见命名方法 序号命名方法解释1全小写2全大写3驼峰:小驼峰命名法4驼峰:大驼峰命名法5烤串命名法 / 脊柱命名法6下划线分隔法 二、项目名 采用小写字母和中划线&#…

NumPy Ndarray学习

1.NumPy Ndarray 对象简介 NumPy 最重要的特点是其 N 维数组对象 ndarray,它是一系列同类型数据的集合,以 0 下标为开始进行集合中元素的索引。ndarray 对象是用于存放同类型元素的多维数组。ndarray 中的每个元素在内存中都有相同存储大小的区域。 2.N…

二:MySQL基础---查询专项练习

目录 表结构 1. 数据月表(zbr_data_monthly_data_YYYYMM) 2. 分类表(zbr_category) 3. 用户表(zbr_user) 4. 交易表(zbr_transaction) 查询知识点 1. 基本查询 2. 连接查询 …

C++线程异步

本文内容来自: 智谱清言 《深入应用C11 代码优化与工程级应用》 std::future std::future作为异步结果的传输通道,可以很方便地获取线程函数的返回值。 std::future_status Ready (std::future_status::ready): 当与 std::future 对象关联的异步操作…

Python小游戏19——滑雪小游戏

运行效果 python代码 import pygame import random # 初始化Pygame pygame.init() # 设置屏幕尺寸 screen_width 800 screen_height 600 screen pygame.display.set_mode((screen_width, screen_height)) pygame.display.set_caption("滑雪小游戏") # 定义颜色 WH…

批量删除redis数据【亲测可用】

文章目录 引言I redis客户端基础操作key的命名规则批量查询keyII 批量删除key使用连接工具进行分组shell脚本示例其他方法III 知识扩展:控制短信验证码获取频率引言 批量删除redis数据的应用: 例如缓存数据使用了新的key存储,需要删除废弃的key。RedisTemplate的key序列化采…

04字符串算法/代码随想录

四、字符串 反转字符串 力扣344 遇到数组双指针真是太好用了&#xff0c;左右指针不断逼近即可&#xff0c;代码也很简单 class Solution {public void reverseString(char[] s) {int fast s.length - 1;int slow 0;while (slow < fast) {char temp s[fast];s[fast] s[…

conda找不到对应版本的pytorch,就会自动下载cpu版本的

踩坑一&#xff1a; conda install pytorch2.0.1 torchvision0.15.2 torchaudio2.0.2 pytorch-cuda11.7 -c pytorch -c nvidia (本人的服务器支持的 且python3.8.20) 先nvidia-smi查看自己cuda支持的最高版本&#xff0c;然后去pytorch官网寻找对应的torch、torchaudio、to…

信息学科平台设计与实现:Spring Boot技术详解

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

二、应用层,《计算机网络(自顶向下方法 第7版,James F.Kurose,Keith W.Ross)》

文章目录 零、前言一、应用层协议原理1.1 网络应用的体系结构1.1.1 客户-服务器(C/S)体系结构1.1.2 对等体&#xff08;P2P&#xff09;体系结构1.1.3 C/S 和 P2P体系结构的混合体 1.2 进程通信1.2.1 问题1&#xff1a;对进程进行编址&#xff08;addressing&#xff09;&#…