# 1.11 使用JSR 330标准注解

从Spring3.0之后，Spring提供了JSR-330标志注解的支持。这些注解和Spring注解一样被进行扫描，如果想使用它们，需要包含下面的jar包：

> 如果你使用maven，那么javax.inject工件可以在标准maven存储库中使用（<https://repo1.maven.org/maven2/javax/inject/javax.inject/1/）。可以将以下依赖项添加到文件pom.xml中：>

```
<dependency>
    <groupId>javax.inject</groupId>
    <artifactId>javax.inject</artifactId>
    <version>1</version>
</dependency>
```

## 1.11.1 使用@Inject 和 @Named 注入

你可以使用 @javax.inject.Inject来替代@Autowired：

```
import javax.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，允许通过Provider.get() 调用按需访问较短作用域的bean或延迟访问其他bean。以下示例提供了前面示例的变体：

```
import javax.inject.Inject;
import javax.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(...);
        ...
    }
}
```

如果要对应注入的依赖项使用限定名，则应使用@Named注解，如下例所示：

```
import javax.inject.Inject;
import javax.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一起使用。这在这里更适用，因为@Jnject没有required的属性。以下两个示例演示如何使用@Inject和@Nullable：

```
public class SimpleMovieLister {

    @Inject
    public void setMovieFinder(Optional<MovieFinder> movieFinder) {
        ...
    }
}
```

```
public class SimpleMovieLister {

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

## 1.11.2 @Component的标准等价物@Named 和 @ManagedBean

除了使用@Component，你也可以使用@javax.inject.Named 或者 javax.annotation.ManagedBean，如下：

```
import javax.inject.Inject;
import javax.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 javax.inject.Inject;
import javax.inject.Named;

@Named
public class SimpleMovieLister {

    private MovieFinder movieFinder;

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

    // ...
}
```

当你使用@Named或者@ManagedBean，你可以同样使用组件扫描：

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

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

## 1.11.3 JSR-330 标准注解的限制

当使用标准注解时，你应该知道一些重要功能不可用，如下表所示：

| Spring              | javax.inject.\*       | javax.inject限制/描述                                                                                                                                                     |
| ------------------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| @Autowired          | @Inject               | @Inject没有required属性，可以使用Java8的Optional代替                                                                                                                              |
| @Component          | @Named / @ManagedBean | JSR-330没有提供组合模式，只有一种方式来标记命名组件                                                                                                                                         |
| @Scope("singleton") | @Singleton            | JSR-330默认范围像Spring的prototype，但是为了和Spring的默认值保持一致，在Spring中定义的JSR-330 bean默认是singleton。如果要使用其他的作用范围，那么需要使用Spring的@Scope注解。javax.inject也提供了一个@Scope注解。但是这个注解仅用来创建你自己的注解。 |
| @Qualifier          | @Qualifier / @Named   | javax.inject.Qualifier只是一个用来构建自定义Qualifier的元注解。具体的字符串限定符（如带value的Spring的@Qualifier）可以通过javax.inject.Named关联。                                                          |
| @Value              | -                     | 没有相同功能                                                                                                                                                                |
| @Required           | -                     | 没有相同功能                                                                                                                                                                |
| @Lazy               | -                     | 没有相同功能                                                                                                                                                                |
| ObjectFactory       | Provider              | javax.inject.Provider是Spring的ObjectFactory的直接替代品，它只使用了较短的get（）方法名。它还可以与Spring的@Autowired结合使用，或者与无注解的构造函数和setter方法结合使用。                                                |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.flydean.com/spring-framework-documentation5/core-technologies/1.the-ioc-container/1.11using-jsr-330-standard-annotations.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
