7.3. 不明确或不满意的依赖关系
当容器无法将注入解析为一个 Bean 时,存在不确定的依赖关系。
当容器无法将注入解析到任何 Bean 时,存在不满意的依赖关系。
容器执行以下步骤来尝试解决依赖项:
- 它解决了所有实现注入点 Bean 类型的限定注解。
-
它过滤掉禁用的 Bean。禁用的 Bean 是
@Alternative
bean,没有被显式启用。
如果依赖项模糊或不满意,容器将中止部署并引发异常。
要修复模糊的依赖关系,请参阅使用 Qualifier 来解析 Ambiguous Injection。
7.3.1. 限定符
限定符是注解,用于避免在容器可以解析多个 Bean 时产生模糊的依赖关系,它们适合注入点。在注入点上声明的限定符提供一组合格的 Bean,后者声明相同的限定符。
限定条件必须以保留和目标声明,如下例所示。
示例:定义 @Synchronous
和 @Asynchronous
Qualifiers
@Qualifier @Retention(RUNTIME) @Target({TYPE, METHOD, FIELD, PARAMETER}) public @interface Synchronous {}
@Qualifier @Retention(RUNTIME) @Target({TYPE, METHOD, FIELD, PARAMETER}) public @interface Asynchronous {}
示例:使用 @Synchronous
和 @Asynchronous
Qualifiers
@Synchronous public class SynchronousPaymentProcessor implements PaymentProcessor { public void process(Payment payment) { ... } }
@Asynchronous public class AsynchronousPaymentProcessor implements PaymentProcessor { public void process(Payment payment) { ... } }
'@Any'
每当 bean 或注入点没有明确声明限定符时,容器会假定限定符 @Default
。您不时需要声明一个注入点而无需指定限定符。这也有限定条件。所有 beans 都具有限定符 @Any
。因此,通过在注入点显式指定 @Any
,您可以抑制默认限定符,而不限制有资格注入的 Bean。
当您想迭代某个 Bean 类型的所有 bean 时,这尤其有用。
import javax.enterprise.inject.Instance; ... @Inject void initServices(@Any Instance<Service> services) { for (Service service: services) { service.init(); } }
每个 bean 都具有限定符 @Any
,即使它没有明确声明此限定符。
每个事件也都有限定符 @Any
,即使它不是明确声明这个限定符的。
@Inject @Any Event<User> anyUserEvent;
@Any
限定符允许注入点引用所有 bean 或特定 bean 类型的所有事件。
@Inject @Delegate @Any Logger logger;