跳到主要内容
版本:7.0.3

使用JSR 330标准注解

Hunyuan 7b 中英对照 Using JSR 330 Standard Annotations

Spring 支持 JSR-330 标准注解(依赖注入)。这些注解的扫描方式与 Spring 自带的注解相同。要使用它们,你需要在类路径中包含相关的 JAR 文件。

备注

如果你使用Maven,jakartainject这个依赖项可以在标准的Maven仓库中找到(https://repo.maven.apache.org/maven2/jakarta/inject/jakarta.inject-api/2.0.0/)。你可以在pom.xml文件中添加以下依赖:

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

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

除了使用@Autowired,你还可以使用@jakartainjectInject,如下所示:

import jakarta.inject.Inject;

public class SimpleMovieLister {

private MovieFinder movieFinder;

@Inject
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}

public void listMovies() {
this.movieFinder.findMovies(...);
// ...
}
}

@Autowired一样,你也可以在字段级别、方法级别和构造函数参数级别使用@Inject。此外,你可以将注入点声明为Provider类型,这样就可以按需访问作用域较小的Bean,或者通过Provider.get()调用延迟访问其他Bean。以下示例提供了前面示例的一个变体:

import jakarta.inject.Inject;
import jakarta.inject.Provider;

public class SimpleMovieLister {

private Provider<MovieFinder> movieFinder;

@Inject
public void setMovieFinder(Provider<MovieFinder> movieFinder) {
this.movieFinder = movieFinder;
}

public void listMovies() {
this.movieFinder.get().findMovies(...);
// ...
}
}

如果想要为需要注入的依赖项使用一个限定名(qualified name),应该使用@Named注解,如下例所示:

import jakarta.inject.Inject;
import jakarta.inject.Named;

public class SimpleMovieLister {

private MovieFinder movieFinder;

@Inject
public void setMovieFinder(@Named("main") MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}

// ...
}

@Autowired一样,@Inject也可以与java.util.Optional@Nullable一起使用。在这里这一点更加适用,因为@Inject没有required属性。以下一对示例展示了如何使用@Inject@Nullable

public class SimpleMovieLister {

@Inject
public void setMovieFinder(Optional<MovieFinder> movieFinder) {
// ...
}
}
public class SimpleMovieLister {

@Inject
public void setMovieFinder(@Nullable MovieFinder movieFinder) {
// ...
}
}

@Named@ManagedBean@Component 注解的标准等价物

@Component不同,你可以使用@jakartainject.Namedjakarta.annotation.ManagedBean,如下例所示:

import jakarta.inject.Inject;
import jakarta.inject.Named;

@Named("movieListener") // @ManagedBean("movieListener") could be used as well
public class SimpleMovieLister {

private MovieFinder movieFinder;

@Inject
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}

// ...
}

通常会直接使用@Component而不为组件指定名称。@Named也可以以类似的方式使用,如下例所示:

import jakarta.inject.Inject;
import jakarta.inject.Named;

@Named
public class SimpleMovieLister {

private MovieFinder movieFinder;

@Inject
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}

// ...
}

当你使用@Named@ManagedBean时,你可以像使用Spring注解一样进行组件扫描,如下例所示:

@Configuration
@ComponentScan(basePackages = "org.example")
public class AppConfig {
// ...
}
备注

@Component不同,JSR-330的@Named和JSR-250的@ManagedBean注解是不可组合的。你应该使用Spring的模板模型来构建自定义组件注解。

JSR-330标准注解的局限性

当你使用标准注释时,你应该知道一些重要的功能是不可用的,如下表所示:

表1. Spring组件模型元素与JSR-330变体对比

Springjakarta.inject.*jakartaInject restrictions / comments
@Autowired@Inject@Inject 没有 ‘required’ 属性。可以替代 Java 8 的 Optional 使用。
@Component@Named / @ManagedBeanJSR-330 不提供可组合的模型,仅提供了一种标识命名组件的方法。
@Scope("singleton")@SingletonJSR-330 的默认作用域类似于 Spring 的 prototype。然而,为了与 Spring 的通用默认设置保持一致,在 Spring 容器中声明的 JSR-330 Bean 默认为 singleton。如果需要使用其他作用域,则应使用 Spring 的 @Scope 注解。jakartainject 也提供了 jakartaInject.Scope 注解,但该注解仅用于创建自定义注解。
@Qualifier@Qualifier / @Namedjakarta.inject.Qualifier 只是用于构建自定义限定符的元注解。具体的 String 限定符(类似于 Spring 带有值的 @Qualifier)可以通过 jakartaInject.Named 关联起来。
@Value-没有相应的注解
@Lazy-没有相应的注解
ObjectFactoryProviderjakarta.inject.Provider 是 Spring 的 ObjectFactory 的直接替代品,只是 get() 方法的名称更短。它也可以与 Spring 的 @Autowired 或未加注解的构造函数及 setter 方法结合使用。