大数跨境
0
0

Spring这几个注解是否用过?

Spring这几个注解是否用过? Spring全家桶实战案例
2025-05-16
0
导读:Spring这几个注解是否用过?

Spring Boot 3实战案例锦集PDF电子书已更新至100篇!

图片

🎉🎉《Spring Boot实战案例合集》目前已更新124个案例,我们将持续不断的更新。文末有电子书目录。

💪💪永久更新承诺

我们郑重承诺,所有订阅合集的粉丝都将享受永久免费的后续更新服务

💌💌如何获取
订阅我们的合集点我订阅,并通过私信联系我们,我们将第一时间将电子书发送给您。

→ 现在就订阅合集

环境:Spring Boot3.4.2




1. 简介

在Java企业开发中,依赖注入(Dependency  Injection,DI)是一种重要的设计模式,它允许我们将对象之间的依赖关系从硬编码中解脱出来,转而由外部容器或框架在运行时动态地注入。Spring框架作为Java领域最流行的IoC容器之一,提供了丰富的依赖注入功能。然而,除了Spring自带的注解(如@Autowired、@Component等)外,Spring还兼容JSR   330规范定义的注解,如@Inject、@Named等。这些注解提供了一种标准的方式来定义依赖,使得代码更加简洁、清晰,并提高了跨框架的兼容性。

JSR 330(Java Specification Request 330)是Java社区过程(Java  Community  Process)中的一个规范,它定义了一套用于依赖注入的注解。这些注解旨在提供一种与具体框架无关的、标准化的方式来定义和注入依赖。Spring框架从早期版本开始就一直支持JSR  330注解,这使得开发者可以在Spring项目中灵活地使用这些注解。

JSR  330注解是跨框架的,这意味着如果你的项目将来需要迁移到其他支持JSR  330的IoC容器或框架(如CDI、Guice等),那么你可以很容易地实现这一迁移,而无需修改大量的代码。

从 Spring 3.0 开始,Spring 支持 JSR-330 标准注解(依赖注入)。这些注解的扫描方式与 Spring 注释相同。要使用这些注解,你需要在类路径中包含相关的依赖即可。

本文将详细介绍在Spring框架中如何使用JSR 330注解进行依赖注入。通过本文的学习,读者将能够掌握在Spring中灵活运用JSR  330注解进行依赖注入的技能,提升项目的可维护性和可扩展性。

2. 实战案例

2.1 引入依赖

<dependency>  <groupId>jakarta.inject</groupId>  <artifactId>jakarta.inject-api</artifactId>  <version>2.0.1</version></dependency>

要在Spring中使用JSR330标准注解,只需要引入上面的依赖即可;Spring内部会自动的处理相关注解,比如:ClassPathBeanDefinitionScanner会自动识别@Named注解的类。

2.2 使用 @Inject 和 @Named 进行依赖注入

@Named注解

使用@Named替换@Component注解定义Bean。

@NamedpublicclassPersonDAO{  // todo}

这里的@Named注解等价于@Component,在上面已经提到了Spring为什么能够识别到@Named注解呢?就是因为ClassPathBeanDefinitionScanner类,在该类中注册的默认过滤器TypeFilter中包含有javax.inject.Named。如下:

// 该类是ClassPathBeanDefinitionScanner的父类public class ClassPathScanningCandidateComponentProvider {  private final List<TypeFilter> includeFilters = new ArrayList<>();  protected void registerDefaultFilters() {    this.includeFilters.add(new AnnotationTypeFilter(Component.class));    ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();    try {      this.includeFilters.add(new AnnotationTypeFilter(          ((Class<? extends Annotation>) ClassUtils.forName("jakarta.annotation.ManagedBean", cl)), false));    }    try {      this.includeFilters.add(new AnnotationTypeFilter(          ((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));    }    try {      this.includeFilters.add(new AnnotationTypeFilter(          ((Class<? extends Annotation>) ClassUtils.forName("jakarta.inject.Named", cl)), false));    }    try {      this.includeFilters.add(new AnnotationTypeFilter(          ((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));    }  }}

该@Named注解还可以指定beanName

@Named("personDAO")publicclassPersonDAO{}

你还可以使用@ManagedBean标注一个类,Spring也会识别该注解。

@ManagedBean("personDAO")publicclassPersonDAO{}

注意:@ManagedBean注解将会在Jakarta EE 11之后删除,所以不推荐使用。

与@Component相比,JSR-330中的@Named注解和JSR-250中的@ManagedBean注解是不可组合的。应该使用Spring的构造型模型来构建自定义组件注释。

@Inject注解

使用@jakarta.inject.Inject 代替@Autowired,如下所示:

@Namedpublic class PersonService {  @Inject  private PersonDAO dao ;  // todo}

也可以用于setter方法上。

private PersonDAO dao ;@InjectpublicvoidsetDao(PersonDAO dao){this.dao = dao ;}

你还可以限定注入bean的名称

@Injectpublic void setDao(@Named("personDAO") PersonDAO dao) {this.dao = dao ;}

这里通过@Named注解来限定你要注入的bean名称。

与 @Autowired 一样,@Inject 也可以与 java.util.Optional 或 @Nullable 一起使用。由于 @Inject 没有必填属性,因此在这里更加适用。下面一对示例展示了如何使用 @Inject 和 @Nullable:

// 容器中不存在CommonDAO也不会报错@Inject private Optional<CommonDAO> commonDAO ;

你也可以使用@Nullable注解,表示可为空,不是必须的。

@Inject@Nullableprivate CommonDAO commonDAO ;

你还可以使用Jakarta EE的Provider类(等价Spring的ObjectProvider)

@Inject private Provider<CommonDAO> commonDAO ;

这样一来,你这里的CommonDAO也可以在容器中不存在。

以上是关于在Spring中使用Jakarta EE标准注解的使用。接下来对比Jakarta EE标准注解与Spring注解的一些对比

3. JSR-330 标准注释的局限性

如下表所示,在使用标准注释时,有些重要功能是不可用的:

Spring
jakarta.inject.* 限制
@Autowired @Inject @Inject 没有 "required "属性。可使用 Java 8 的 Optional 代替。
@Component @Named JSR-330 没有提供可组合模型,只是提供了一种识别已命名组件的方法。
@Scope("singleton") @Singleton JSR-330 的默认作用域与 Spring 的原型类似。不过,为了与 Spring 的一般默认设置保持一致,在 Spring 容器中声明的 JSR-330 Bean 默认为单例。jakarta.inject 也提供了 jakarta.inject.Scope 注解:不过,该注解仅用于创建自定义注解。
@Qualifier @Qualifier jakarta.inject.Qualifier 只是一个元注解,用于构建自定义限定符。通过 jakarta.inject.Named.Qualifier 可以关联具体的字符串限定符(如 Spring 的带值 @Qualifier)。
@Value
-
无对应
@Lazy
-
无对应
ObjectFactory Provider jakarta.inject.Provider 是 Spring ObjectFactory 的直接替代品,只是 get() 方法的名称更短。它还可以与 Spring 的 @Autowired 或非注释构造函数和设置方法结合使用。
以上是本篇文章的全部内容,如对你有帮助帮忙点赞+转发+收藏

推荐文章

天呐!Java Stream 高效开发!16 个逆天案例,让你秒速起飞!

Spring Boot 多版本API控制 5 种实现方案

高级开发!自定义注解100行代码实现 @Resource/@Autowired 注入功能

太赞了!AOP弃用@Aspect,一个注解让你的代码灵活十倍!

强大!Spring Boot 一个注解搞定接口限流

王炸!Spring AI+MCP 三步实现智能体开发

太强了!JavaParser:代码修改、生成与分析的全能利器

王炸!Spring AI+Tools 一分钟实现CRUD智能助手

Spring Cloud Gateway 网关非常实用的8个开发技巧,你知道吗?太实用了

太强!SpringBoot+Lua搞定Redis原子操作

提升性能!使用Reactor合并三方接口请求

【声明】内容源于网络
0
0
Spring全家桶实战案例
Java全栈开发,前端Vue2/3全家桶;Spring, SpringBoot 2/3, Spring Cloud各种实战案例及源码解读
内容 832
粉丝 0
Spring全家桶实战案例 Java全栈开发,前端Vue2/3全家桶;Spring, SpringBoot 2/3, Spring Cloud各种实战案例及源码解读
总阅读195
粉丝0
内容832