Java依赖注入
依赖注入是IoC的一种特定形态,是指寻找依赖项的过程不在当前执行代码的直接控制之下。Java中为依赖注入的容器有Guice,Spring和PicoContainer.
javax.inject包
这个包指明了获取对象的一种方式,与传统的构造方法,工厂模式和服务定位器模式(比如JNDI)等相比,这种方式的可重用性,可测试性和可维护性都得到了极大提升。这种方式称为依赖注入,对于大多数非小型应用程序都很有帮助。
javax.inject包里包括一个Provider@Inject,@Qualifier,@Named,@Scope和@Singleton
)
@Inject注解
出现在三种类型成员之前,表示该成员需要注入依赖项
- 构造器 —-其参数在运行时由配置好的IoC容器提供(注入的参数数量为0或多个)
- 方法 —-其参数在运行时由IoC容器提供(注入的参数数量为0或多个,)
- 属性 —-只有不是final的才能注入,虽然简单,但最好不要用,这样可能会让单元测试更加困难
@Qualifier注解
限定(标识)要注入的对象,如在IoC容器中有两个类型相同的对象,注入时要把它们区分开
创建一个@Qualifier实现必须遵循如下规则:
- 必须标记为@Qualifier和@Retention(RUNTIME),以确保该限定注解在运行时一直有效
- 通常还应该加上@Documented注解,这样该实现就能加到API的公共JavaDoc中了
- 可以有属性
- @Target注解可以限定其使用范围,比如将其使用范围限制为属性,而不是限定为属性的默认值和方法的参数。
JSR-330规范中要求所有IoC容器都要提供一个默认的@Qualifier注解 :@Named
@Named
它是一个特别的@Qualifier注解,借助它可以用名字标明要注入的对象。将@Named和@Inject一起使用,符合指定名称并且类型正确的对象会被注入。
@Scope注解
它用于定义注入器(IoC容器)对注入对象的重用方式。JSR330规范中明确了如下几种默认行为:
- 如果没有声明任何@Scope注解接口的实现,注入器应该创建注入对象并且仅使用该对象一欠
- 如果声明了@Scope注解接口的实现,那么注入对象的生命周期由所声明的@Scope注解实现决定
- 如果注入对象在@Scope实现中要由多个线程使用,则需要保证注入对象的线程安全性
- 如果某个类上声明了多个@Scope注解,或声明了不受支持的@Scope注解,IoC容器应该抛出异常
因为大家公认的通知@Scope实现只有@Singleton一个,所以JSR330中仅确定了它这么一个标准的生命周期注解
@Singleton注解
@Singleton注解接口在DI框架中应用广泛,在需要注入一个不会改变的对象时,就要用@Singleton.
大多数DI框架都将@Singleton作为注入对象的默认生命周期,无需显式声明。