《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。
publicclassPersonDAO{// 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
publicclassPersonDAO{}
你还可以使用@ManagedBean标注一个类,Spring也会识别该注解。
publicclassPersonDAO{}
注意:@ManagedBean注解将会在Jakarta EE 11之后删除,所以不推荐使用。
与@Component相比,JSR-330中的@Named注解和JSR-250中的@ManagedBean注解是不可组合的。应该使用Spring的构造型模型来构建自定义组件注释。
@Inject注解
使用@jakarta.inject.Inject 代替@Autowired,如下所示:
@Namedpublic class PersonService {@Injectprivate PersonDAO dao ;// todo}
也可以用于setter方法上。
private PersonDAO dao ;publicvoidsetDao(PersonDAO dao){this.dao = dao ;}
你还可以限定注入bean的名称
public void setDao(("personDAO") PersonDAO dao) {this.dao = dao ;}
这里通过@Named注解来限定你要注入的bean名称。
与 @Autowired 一样,@Inject 也可以与 java.util.Optional 或 @Nullable 一起使用。由于 @Inject 没有必填属性,因此在这里更加适用。下面一对示例展示了如何使用 @Inject 和 @Nullable:
// 容器中不存在CommonDAO也不会报错private Optional<CommonDAO> commonDAO ;
你也可以使用@Nullable注解,表示可为空,不是必须的。
private CommonDAO commonDAO ;
你还可以使用Jakarta EE的Provider类(等价Spring的ObjectProvider)
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 个逆天案例,让你秒速起飞!
高级开发!自定义注解100行代码实现 @Resource/@Autowired 注入功能
太赞了!AOP弃用@Aspect,一个注解让你的代码灵活十倍!
太强了!JavaParser:代码修改、生成与分析的全能利器
王炸!Spring AI+Tools 一分钟实现CRUD智能助手
Spring Cloud Gateway 网关非常实用的8个开发技巧,你知道吗?太实用了


