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

时间:2015-11-29 01:31:01

标签: dependency-injection cdi weld

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

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

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

我准备了一个提供者类。

@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抱怨

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()]

这是正常的吗?或CDI的工作方式与DI不同?

1 个答案:

答案 0 :(得分:3)

是的,这是预料之中的。注入点的Bean解析由Highlander原则控制:"只能有一个。"

来自CDI spec

  

如果bean没有显式声明@Named以外的限定符,   bean只有一个额外的限定符,类型为@Default。这个   被称为默认限定符。

and

  

如果注入点声明没有限定符,则注入点只有一个限定符,即默认限定符@Default。

因此,您的不合格注射点确实与三个豆匹配。

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