焊接CDI:如何使一个bean类满足多个限定符中的任何一个?

时间:2011-09-22 10:40:59

标签: code-injection cdi jboss-weld qualifiers

从阅读Weld文档我不认为可以做到这一点,但我真的可以做到,所以我想问一下 - 如果CDI没有办法,也许有一种模式解决方法... < / p>

我已经创建了一个带有成员的自定义限定符:

@Qualifier
@Target({TYPE, METHOD, FIELD, PARAMETER})
@Retention(RUNTIME)
public @interface JobBinding {
    JobType value();
}

JobType是一个枚举:

public enum JobType {

    JOB_A,
    JOB_B,
// etc - there are quite a few

假设大多数工作需要以稍微不同的方式构建,因此我有与工作相关的构建器类。在给定相关JobType的情况下,使用JobBinding注释对它们进行注释:

@JobBinding(JobType.JOB_A)
public class JobABuilder implements JobBuilder {
....

当我需要构建时,我使用程序化查找:

@Inject @Any
private Instance<JobBuilder> builderSource;
private JobType myJobType;
...
builderSource.select(new JobBindingQualifier(myJobType).get();

JobBindingQualifier是一个自定义类:

public class JobBindingQualifier extends AnnotationLiteral<JobBinding> implements JobBinding {

    private static final long serialVersionUID = -822150300665931157L;

    private JobType type;

    public JobBindingQualifier(JobType type) {
        this.type = type;
    }

    @Override
    public JobType value() {
        return type;
   }
}

到目前为止,伟大的 - CDI工作出色。但是,如果其中两个作业JOB_X和JOB_Y以完全相同的方式构建呢?我只需要一个构建器类,我希望为其中任何一个选项实例化它们new JobBindingQualifier(JobType.JOB_X)new JobBindingQualifier(JobType.JOB_Y)

如果我同时使用JobXAndYBuilder@JobBinding(JOB_X)注释@JobBinding(JOB_Y),则会出现有关重复注释的编译错误。为了解决这个问题,我可以将注释的值更改为JobTypes数组,并且您可以为构建器添加注释

@JobBinding(JobType.JOB_X, JobType.JOB_Y)

使用省略号在那里调用构造函数来生成数组。但是,如果我这样做,我怎样才能使用任何一个jobTypes 以编程方式查找?焊接文档建议你必须两个;我需要提供准确的参数:

builderSource.select(new JobBindingQualifier(JobType.JOB_X, JobType.JOB_Y).get();

当我想要足以查找该类时:

builderSource.select(new JobBindingQualifier(JobType.JOB_X).get();
//or
builderSource.select(new JobBindingQualifier(JobType.JOB_Y).get();

使用数组实际上只是改变了查找时必须匹配的值。我真的需要一种使用相同的限定符注释两次注释类的方法,然后能够使用它们的任意组合来查找它。否则,我必须为X和Y提供一个构建器类,当一个就足够了。有任何想法吗?提前谢谢!

1 个答案:

答案 0 :(得分:2)

正如我在评论中所说,当你在bean类上有两个或更多限定符时,没有直接的方法来建立OR关系。

因此,使用另一个限定符具有相同Bean的解决方案是使用Producer机制。在您的示例中,您可以像往常一样创建第一个类:

@JobBinding(JobType.JOB_X)
public class JobABuilder implements JobBuilder {
    ....
}

然后在第一个类或者像

这样的专用生成器类中创建一个生成器方法
public class MoreJobsProducer {
    @Produces
    @JobBinding(JobType.JOB_Y)
    protected JobBuilder prodJobYBuilder(@New @JobBinding(JobType.JOB_X)
                                         JobBuilder theJob) {
        return theJob;
    }    
}

在生成器方法的参数中,您使用自己的限定符和@New限定符注入您的前bean,以创建bean的新实例以确保避免一些范围问题(阅读Weld doc以获取更多信息)信息)。

它应该做“工作”。