从阅读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提供一个构建器类,当一个就足够了。有任何想法吗?提前谢谢!
答案 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以获取更多信息)信息)。
它应该做“工作”。