1.11 使用JSR330标准注解

Spring3.0开始,Spring提供对JSR-330标准注解的支持(依赖注入)。这些注解和Spring注解一样的方式被扫描。去使用它们,你需要在类路径中依赖相关的jar包。

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,从而允许按需访问范围较短的bean,或者通过提供程序get()调用对其他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。这在这里更适用,因为@Inject没有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 @Named@ManagedBean:等价于@Component

代替@Component,你可以使用@javax.inject.Namedjavax.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时,可以使用与使用Spring注解完全相同的方式来使用组件件扫描。类似下面例子展示:

@Configuration
@ComponentScan(basePackages = "org.example")
public class AppConfig  {
    // ...
}
1.11.3 JSR-330标准注解的限制

当你使用标准注解时,你应该知道一些重要特性不可用,类似下面表格展示:

@Autowired@Inject@Inject没有 required属性. 能够使用在Java8的 Optional
@Component@Named / @ManagedBeanJSR-330不提供可组合的模型,仅提供一种识别命名组件的方法。
@Scope("singleton")@SingletonJSR-330 默认作用域是 Spring的 prototype. 然而, 为了保存与Spring的一般默认一致性, 在Spring容器中JSR-330bean默认被声明为一个singleton。为了使用其他的作用域,你应该使用Spring的@Scope注解。javax.inject也提供一个@Scope注解。不过,此仅用于创建自己的注解。
@Qualifier@Qualifier / @Namedjavax.inject.Qualifier是构建自定义限定符元注解. 具体的 String 限定通过javax.inject.Named关联。 (类似Spring的 @Qualifier 值)
@Value-no equivalent
@Required-no equivalent
@Lazy-no equivalent
ObjectFactoryProviderjavax.inject.Provider是Spring的ObjectFactory的直接替代,仅仅有一个get()方法名,它也可以与Spring的@Autowired结合使用,也可以与无注释的构造函数和setter方法结合使用。

作者

博客地址: http://youngitman.tech

CSDN: https://blog.csdn.net/liyong1028826685

微信公众号:Spring 5 中文解析核心篇-IoC容器之JSR330标准注解-LMLPHP

技术交流群:Spring 5 中文解析核心篇-IoC容器之JSR330标准注解-LMLPHP

09-10 00:19