IoC容器11——使用JSR 330 标准注解

原创
2017/07/10 14:30
阅读数 690

使用JSR 330 标准注解

从Spring 3.0开始,提供对JSR 330标准注解(依赖注入)的支持。这些注解与Spring注解以相同的方式进行扫描。需要添加相关的jar文件到类路径。

如果使用Maven,那么javax.inject artifact 在标准Maven存储库中可用http://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 使用@Inject和@Named进行依赖注入

作为@Autowired的替代,@javax.inject.Inject使用如下:

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

如果对将要注入的依赖使用限定名,可以像下面一样使用@Name注解:

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

    // ...
}

2 @Named和@ManageBean:@Component注解的标准等价形式

作为@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;
    }

    // ...
}

当使用@Name或@ManagedBean时,可以用与使用Spring注解完全相同的方式进行组件扫描:

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

与@Component相反,JSR-330的@Name和JSR-250的@ManagedBean不可组合。请使用Spring的原型模型来构建自定义的组件注解。

3 标准JSR-330注解的局限

当使用标准注解时,重要的是要知道一些重要的功能是不可用的,如下表所述:

Spring javax.inject.* javax.inject 限制/ 注释
@Autowired @Inject @Inject 没有 'required' 属性;可以使用Java 8 的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仅仅是构建自定义限定值的元注解。具体的字符串限定值(类似带值的Spring@Qualifier注解)可以通过javax.inject.Named关联
@Value - 没有等价形式
@Required - 没有等价形式
@Lazy - 没有等价形式
ObjectFactory Provider javax.inject.Provier是Spring的ObjectFactory的直接替代方法,只需要一个较短的get()方法名称。它也可以与Spring的@Autowired或非注解知识的构造函数和setter方法结合使用。
展开阅读全文
加载中

作者的其它热门文章

打赏
0
0 收藏
分享
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部