9.spring framework 5.2.3.RELEASE 文档之核心技术(Core Technologies) 第八篇 使用JSR-330 标准注解

1.11. 使用JSR 330 标准注解

从Spring 3.0开始,Spring提供对JSR-330标准注解(依赖注入)的支持。 这些注解的扫描方式与Spring注解的扫描方式相同。 要使用它们,您需要在类路径中有相关的jar。

如果使用Maven,则标准Maven存储库(https://repo1.maven.org/maven2/javax/inject/javax.inject/1/)中提供了javax.inject组件。 您可以将以下依赖项添加到文件pom.xml中:

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

 

 

1.11.1. 依赖注入使用 @Inject and @Named 

代替@Autowired,你可以使用@javax.inject.Inject 如下:

java

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(...);
        // ...
    }
}

kotlin

import javax.inject.Inject

class SimpleMovieLister {

    @Inject
    lateinit var movieFinder: MovieFinder


    fun listMovies() {
        movieFinder.findMovies(...)
        // ...
    }
}

与@Autowired一样,您可以在字段级别,方法级别和构造函数参数级别使用@Inject。 此外,您可以将注入点声明为Provider,从而允许按需访问范围较小的bean,或者通过Provider.get()调用来延迟访问其他bean。 以下示例提供了前面示例的变体:

java

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(...);
        // ...
    }
}

kotlin

import javax.inject.Inject

class SimpleMovieLister {

    @Inject
    lateinit var movieFinder: MovieFinder


    fun listMovies() {
        movieFinder.findMovies(...)
        // ...
    }
}

如果要为应注入的依赖项使用限定名称,则应使用@Named注解,如以下示例所示:

java

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;
    }

    // ...
}

kotlin

import javax.inject.Inject
import javax.inject.Named

class SimpleMovieLister {

    private lateinit var movieFinder: MovieFinder

    @Inject
    fun setMovieFinder(@Named("main") movieFinder: MovieFinder) {
        this.movieFinder = movieFinder
    }

    // ...
}

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

public class SimpleMovieLister {

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

java

public class SimpleMovieLister {

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

kotlin

class SimpleMovieLister {

    @Inject
    var movieFinder: MovieFinder? = null
}

1.11.2. @Named和@ManagedBean:与@Component注解标准相等

可以使用@ javax.inject.Named或javax.annotation.ManagedBean代替@Component,如以下示例所示:

java

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;
    }

    // ...
}

kotlin

import javax.inject.Inject
import javax.inject.Named

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

    @Inject
    lateinit var movieFinder: MovieFinder

    // ...
}

在不指定组件名称的情况下使用@Component是非常常见的。 可以类似的方式使用@Named,如以下示例所示:

java

import javax.inject.Inject;
import javax.inject.Named;

@Named
public class SimpleMovieLister {

    private MovieFinder movieFinder;

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

    // ...
}

kotlin

import javax.inject.Inject
import javax.inject.Named

@Named
class SimpleMovieLister {

    @Inject
    lateinit var movieFinder: MovieFinder

    // ...
}

当使用@Named或@ManagedBean时,可以使用与使用Spring注解完全相同的方式来使用组件扫描,如以下示例所示:

java

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

kotlin

@Configuration
@ComponentScan(basePackages = ["org.example"])
class AppConfig  {
    // ...
}
与@Component相反,JSR-330 @Named和JSR-250 ManagedBean注解是不可组合的。 您应该使用Spring的构造型模型来构建自定义组件注解。

1.11.3. 标准的JSR-330注解的局限性

JSR-330的局限性使用标准注解时,您应该知道某些重要功能不可用,如下表所示:标准注解

Table 6. Spring component model elements versus JSR-330 variants
Springjavax.inject.*javax.inject restrictions / comments

@Autowired

@Inject

@Inject没有'required'属性。 可以与Java 8的可选一起使用。

@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只是用于构建自定义限定符的元注解。 可以通过javax.inject.Named关联具体的string限定词(例如带有值的Spring的@Qualifier)。

@Value

-

no equivalent

@Required

-

no equivalent

@Lazy

-

no equivalent

ObjectFactory

Provider

javax.inject.Provider是Spring的ObjectFactory的直接替代品,只是具有较短的get()方法名称。 它也可以与Spring的@Autowired结合使用,也可以与无注解的构造函数和setter方法结合使用。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值