7.3. 不明确或不满意的依赖关系
当容器无法将注入解析为一个 Bean 时,存在不确定的依赖关系。
当容器无法将注入解析到任何 Bean 时,存在不满意的依赖关系。
容器执行以下步骤来尝试解决依赖项:
- 它解决了所有实现注入点 Bean 类型的限定注解。
-
它过滤掉禁用的 Bean。禁用的 Bean 是
@Alternativebean,没有被显式启用。
如果依赖项模糊或不满意,容器将中止部署并引发异常。
要修复模糊的依赖关系,请参阅使用 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;