如何让 Weld 区分 [@Default@Any@Named] 和 [@Default@Any]?

How can I make Weld to distinguish [@Default@Any@Named] from [@Default@Any]?

我正在使用 weld-se 来测试我的 JSR-330 注释之一 class。

@Inject HelloWorld any;
@Inject @Named("impl") HelloWorld namedAsImpl;
@Inject @Named("demo") HelloWorld namedAsDemo;
@Inject @Impl HelloWorld qualifiedWithImpl;
@Inject @Demo HelloWorld qualifiedWithDemo;

我成功地用 Guice、Dagger 和 Dagger2 注入了这些字段。

我准备了一个供应商class。

@RequestScoped
public class HelloWorldWeldProvider {

    @Produces HelloWorld any() {
        return current().nextBoolean()
               ? new HelloWorldImpl() : new HelloWorldDemo();
    }

    @Produces @Named("impl") HelloWorld namedAsImpl() {
        return new HelloWorldImpl();
    }

    @Produces @Named("demo") HelloWorld namedAsDemo() {
        return new HelloWorldDemo();
    }

    @Produces @Impl HelloWorld qualifiedWithImpl() {
        return new HelloWorldImpl();
    }

    @Produces @Demo HelloWorld qualifiedWithDemo() {
        return new HelloWorldDemo();
    }
}

韦尔德抱怨

WELD-001409: Ambiguous dependencies for type HelloWorld with qualifiers @Default
  at injection point [BackedAnnotatedField] @Inject ....any
  at ....any(HelloWorldDependencyInjectionTest.java:0)
  Possible dependencies: 
  - Producer Method [HelloWorld] with qualifiers [@Default @Any @Named] declared as [[BackedAnnotatedMethod] @Produces @Named ....namedAsDemo()],
  - Producer Method [HelloWorld] with qualifiers [@Default @Any @Named] declared as [[BackedAnnotatedMethod] @Produces @Named ....namedAsImpl()],
  - Producer Method [HelloWorld] with qualifiers [@Any @Default] declared as [[BackedAnnotatedMethod] @Produces ....any()]

这正常吗?还是 CDIDI 的工作方式不同?`

是的,这是预期的。注入点的 Bean 解析受 Highlander 原则约束:"There can be only one."

来自CDI spec

If a bean does not explicitly declare a qualifier other than @Named, the bean has exactly one additional qualifier, of type @Default. This is called the default qualifier.

and

If an injection point declares no qualifier, the injection point has exactly one qualifier, the default qualifier @Default.

所以你不合格的注入点确实匹配了三个bean

你的第二个问题CDI 与 DI 有什么不同吗? 取决于你对 DI 的定义。如果你的意思是 DI = JSR330,那么答案是肯定的,否则创建新规范就没有意义了。