为了统一各种依赖注入框架的编程模型,JCP发布了Java依赖注入规范,JCP将其称为JSR-330.从Spring3开始,Spring已经开始兼容该注入模型
@Inject是JSR-330的核心部件。该注解几乎可以完全替代Spring的@Autowried注解。
@Inject private Foo foo
和@Autowried一样,@Inject可以自动装配属性、方法和构造器。
但和@Autowried不同的是,@Inject没有required属性。因此,@Inject的注解标注的依赖关系必须存在,如果不存在,则会抛出异常。
除了@Inject注解,JSR-330还提供了另外一种技巧,语气直接注入一个引用,不如要求@Inject注入一个Provider。Provider借口可以实现Bean引用的延迟注入以及注入Bean的多个实例等功能。
例如,我们有一个KnifeJuggler类需要注入一个或者多个Knife的实例。假设Knife Bean的作用域为prototype(非单例),下面的KnifeJuggle的构造器将获得5哥KnifeBean。
private Set<Knife> knives; @Inject public KnifeJuggle(Provider<Knife> knifeProvider){ knives = new HashSet<Knife>(); for (int i=0;i<5;i++){ knives.add(knifeProvider.get()); } }
KnifeJuggler将获得一个Provider<Knife>,而不是在构造器中获得一个knife实例。这个时候,只有Provider被注入进去;在调用knifeprovide.get()方法钱,实际的knife并没有被注入进去。调用5次,放入5个不同的knife对象。
限定@Inject所标注的属性
与@autowired的限定@qualifier类似,@Inject的限定为@Named。
@Inject @Named(”guitar“) private Foo foo;
Spring的@qualifier与JSR-330的@Named的关键区别在语义层面。@qualifier注解是缩小所拼配bean的选择范围(默认是Bean的id),而@Name通过Bean的Id来标示的。
创建自定义的JSR-330的Qualifier
与@Autowried的自定义Qualifier几乎一样,唯一区别注解的导入生声明。如下
//spring的@Autowried的@Qualifier自定义声明 import org.springframework.beans.factory.annotation.Qualifier; //JSR-330 @Inject的@Qualifier自定义声明 import javax.inject.Qualifier;