7.3. 不明确或不满意的依赖关系


当容器无法将注入解析为一个 Bean 时,存在不确定的依赖关系。

当容器无法将注入解析到任何 Bean 时,存在不满意的依赖关系。

容器执行以下步骤来尝试解决依赖项:

  1. 它解决了所有实现注入点 Bean 类型的限定注解。
  2. 它过滤掉禁用的 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 {}
Copy to Clipboard Toggle word wrap

@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface Asynchronous {}
Copy to Clipboard Toggle word wrap

示例:使用 @Synchronous@Asynchronous Qualifiers

@Synchronous
public class SynchronousPaymentProcessor implements PaymentProcessor {
   public void process(Payment payment) { ... }
}
Copy to Clipboard Toggle word wrap

@Asynchronous
public class AsynchronousPaymentProcessor implements PaymentProcessor {
   public void process(Payment payment) { ... }
}
Copy to Clipboard Toggle word wrap
'@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();

   }

}
Copy to Clipboard Toggle word wrap

每个 bean 都具有限定符 @Any,即使它没有明确声明此限定符。

每个事件也都有限定符 @Any,即使它不是明确声明这个限定符的。

@Inject @Any Event<User> anyUserEvent;
Copy to Clipboard Toggle word wrap

@Any 限定符允许注入点引用所有 bean 或特定 bean 类型的所有事件。

@Inject @Delegate @Any Logger logger;
Copy to Clipboard Toggle word wrap

7.3.2. 使用 Qualifier 解决 Ambiguous Injection

您可以使用限定符解决模糊注入问题。阅读有关 Ambiguous 或 Unsatisfidened 依赖项 模糊注入的更多信息。

以下示例模糊不清,并且有两个 Welcome 实施 一种是转换,另一个是没有实现。需要指定注入以使用转换 Welcome

示例:Ambiguous Injection

public class Greeter {
  private Welcome welcome;

  @Inject
  void init(Welcome welcome) {
    this.welcome = welcome;
  }
  ...
}
Copy to Clipboard Toggle word wrap

使用 Qualifier 解析 Ambiguous Injection
  1. 要解决模糊注入,请创建一个名为 @Translating 的限定注释:

    @Qualifier
    @Retention(RUNTIME)
    @Target({TYPE,METHOD,FIELD,PARAMETERS})
    public @interface Translating{}
    Copy to Clipboard Toggle word wrap
  2. 使用 @ Translating 注释给转换 Welcome 标注:

    @Translating
    public class TranslatingWelcome extends Welcome {
        @Inject Translator translator;
        public String buildPhrase(String city) {
            return translator.translate("Welcome to " + city + "!");
        }
        ...
    }
    Copy to Clipboard Toggle word wrap
  3. 请求注入中的 Welcome。您必须明确请求合格的实施,类似于工厂方法模式。这种不确定性是在注入点解决的。

    public class Greeter {
      private Welcome welcome;
      @Inject
      void init(@Translating Welcome welcome) {
        this.welcome = welcome;
      }
      public void welcomeVisitors() {
        System.out.println(welcome.buildPhrase("San Francisco"));
      }
    }
    Copy to Clipboard Toggle word wrap
返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat