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.mzph.cn/web/58109.shtml

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

相关文章

jvm学习笔记-轻量级锁内存模型

一,轻量级锁 LockRecord的那个第一个成员变量是拷贝对应锁定了的java对象资源的MarkWord,Lock Record有一个Ptr指针刚开始指向自己,后面这个指针存储在锁定资源的java对象的markword中,后续可以通过java对象的MarkWord快速定位到…

C++在游戏领域的主要应用

1、C简介 C是一种通用的程序设计语言,其设计就是为了使认真的程序员工作得更愉快。除了一些小细节之外,C是C程序设计语言的一个超集。C提供了C所提供的各种功能还为定义新类型提供了灵活而有效的功能。程序员可以通过定义新类型,使这些类型与…

什么是制造项目管理?

制造项目管理是指在制造行业中管理和协调各类项目活动的过程,以实现产品的有效生产。这类项目通常涉及复杂的资源配置、流程优化、成本控制和质量管理,旨在确保产品按时、按质地完成,并满足市场需求。制造项目在现代工业中非常常见&#xff0…

【力扣专题栏】面试题 01.02. 判定是否互为字符重排,如何利用数组模拟哈希表解决两字符串互排问题?

题解目录 1、题目描述解释2、算法原理解析3、代码编写(1)、两个数组分别模拟哈希表解决(2)、利用一个数组模拟哈希表解决问题 1、题目描述解释 2、算法原理解析 3、代码编写 (1)、两个数组分别模拟哈希表解决 class Solution { public:bool CheckPermutation(string s1, stri…

指针和内存地址的关系(uint8_t和uint32_t的指针有什么区别)

指针在我们的学习中非常常见,有些人只是了解指针的基本概念,却不知道他的原理,到时候使用起来一头雾水,接下来我将对指针做出一些解释说明。 一、数据是如何存储的: 我们初始化一个int变量a,变量a会存储到内存中&#…

【基于LSM的ELF文件安全模块设计】参考

《基于LSM的ELF文件安全模块设计文档》 一、设计目标 本设计致力于通过 Linux 安全模块(LSM)构建一个强大而严密的安全防护体系,以实现对 ELF 文件(涵盖可执行文件和动态链接库)的绝对严格的合法性和完整性检查。其核…

flutter 专题四 Flutter渲染流程

一、 Widget - Element - RenderObject关系 二、 Widget 、Element 、RenderObject 分别表示什么 2.1 Widget Widget描述和配置子树的样子 Widget就是一个个描述文件,这些描述文件在我们进行状态改变时会不断的build。但是对于渲染对象来说,只会使用最…

高效内容营销策略提升品牌影响力与客户忠诚度

内容概要 内容营销是一种通过创造和分享有价值的内容,以吸引特定目标受众并促进品牌发展的策略。这种营销形式不仅仅注重产品的直接推广,更着眼于与受众之间建立长期的信任关系。有效的内容营销能够提升品牌在市场中的影响力和客户的忠诚度,…

vue3 ref和reactive踩坑

起因:开发时做一个列表状态筛选,遇到了数据更新但视图层没有更新的情况,把数据改为ref去操作即完成响应式数据的更新。 const hourRoomTableData reactive([]}if (val 1) {hourRoomTableData hourRoomTableData.filter((item) > item.i…

git 入门作业

任务1: 破冰活动:自我介绍任务2: 实践项目:构建个人项目 git使用流程: 1.将本项目直接fork到自己的账号下,这样就可以直接在自己的账号下进行修改和提交。 这里插一条我遇到的问题,在fork的时候没有将那个only camp4的…

学webpack之loader原理,让面试官跪下来唱征服

引言 什么是loader? 众所周知,webpack是个只能识别js和json文件的小笨蛋,所以就要有loader来转换,让文件能被webpack识别到,从而顺利打包,loader还能对资源进行优化,如压缩图片,代…

前端如何优化页面中的大量任务

直奔主题,如果页面中有100万个任务需要执行,怎么保证页面不卡顿? 可以采取以下几种策略: 任务分片执行: 利用requestIdleCallback和requestAnimationFrame来分片执行任务。requestIdleCallback可以在浏览器空闲时执行…

NumPy Ndarray学习

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

网络层3——IP数据报转发的过程

目录 一、基于终点的转发 1、理解 2、IP数据报转发过程 二、最长前缀匹配 1、理解 2、主机路由 3、默认路由 三、二叉线索查找 一、基于终点的转发 1、理解 理解什么叫终点转发 IP数据报的传递,交给路由器后 可不可以做到直接发送给目的主机呢?…

【UGUI】为射击游戏添加动态显示的分数和血量到UI界面

项目背景 在这个项目中,我们希望实现一个简单的游戏系统,其中玩家可以通过击中目标来获得分数,同时通过与怪物碰撞来减少血量。分数和血量需要在游戏界面上实时显示,以便玩家能够随时了解自己的状态。 技术实现 1. 静态变量的使…

使用Spring Boot搭建简单的web服务

1 引言 1.1 Spring Boot简介 Spring Boot是由Pivotal团队提供的一套开源框架,旨在简化Spring应用的创建及部署。 一、核心设计思想 Spring Boot的核心设计思想是“约定优于配置”(Convention Over Configuration,简称COC)。这…

「C/C++」C/C++标准库 之 #include<cstdlib> 通用工具函数库

✨博客主页何曾参静谧的博客📌文章专栏「C/C」C/C程序设计📚全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…

CTF压缩包破解神器bkcrack教程和详细使用过程

kali安装bkcrack教程和详细使用过程 1.bkcrack介绍:2.bkcrack功能:3.bkcrack安装:Linux-Kali下:测试:Windows下安装: 4.bkcrack的使用方法:4.1查看相关参数4.2恢复内部密钥从 zip 档案中加载数据…

基于Python的乡村居民信息管理系统【附源码】

基于Python的乡村居民信息管理系统 效果如下: 系统主页面 系统登录页面 管理员主页面 居民管理页面 政务学习页面 土地信息管理页面 个人信息管理页面 居民登陆页面 村委人员主页面 研究背景 随着信息技术的飞速发展和乡村振兴战略的深入实施,传统的乡…

UI设计公司—兰亭妙微—提供轨道交通行业UI设计

蓝蓝设计工作室2008年开始,2011年正式成立北京兰亭妙微科技有限公司,主创清华团队,专注软件和互联网ui设计开发,擅长企业信息化管理、监控、大数据软件UIUE咨询和设计开发服务。立足UI,一直在学习进步。交通行业UE UI解…