如果没有定义其他生产者,则定义@Default 生产者

Define @Default producer if no other is defined

当我有一个在某些环境中提供的 bean 生产者时,如果没有其他生产者,我如何将我的生产者注释为可用 @Default

给定生产者方法

@Produces 
public Foo produce() 

还有另一个我无法控制的代码中的生产者方法:

@Produces 
public Foo produceIt() 

两者都有一个隐含的@Default 注释和冲突。 但第二个并非在所有环境中都可用。

编辑:所以我在第一个(我控制)中添加了另一个限定符@FooProducer,这使得它在第二个可用时工作 - 但这删除了隐式@Default,所以有 NO 生产者(类型匹配但 none 找到 @Default)如果第二个不在类路径上则可用。

如果第二个可用,如何将第一个生产者注释为默认,如果有则不冲突另一个默认生产者?

Weld 的文档看来,声明您的制作人 @Alternative 并使用任何 @Priority 全局启用它应该可以解决问题:

@Priority(100)
public class YourFactory {

    @Produces @Alternative
    public Foo produce() 
}

如果您无法控制默认生产者,并且不知道它是否会在运行时出现,您将不得不使用 @Any 限定符和 Instance 作为注入指向在运行时解析 bean。

试试这个:

  1. 为后备生成器定义限定符,使其不是默认生成器。你已经这样做了,但我会使用更有意义的东西而不是 @FooProducer,比如 @Fallback.

    @制作 @倒退 public Foo produce()

  2. 将注入点更改为 Instance<Foo> 并使用限定符 @Any

    @任何 私有实例 fooProvider;

  3. 要在运行时获取 Foo 实例,您必须检查该实例是否不明确。如果是,select 默认生产者,否则它将 return 唯一可用的生产者,即您用 @Fallback.

    注释的生产者

    AnnotationLiteral defaultLiteral = new AnnotationLiteral<>() {};

    富富 = fooProvider.isAmbiguous() ? fooProvider.select(defaultLiteral).get() : fooProvider.get();

对于 CDI 2.0,您可以使用 Default.Literal.INSTANCE 而不是 defaultLiteral