2

通过阅读 Weld 文档,我认为这无法做到,但我真的可以做到,所以我想我会问 - 如果 CDI 没有办法,也许有一种模式解决方法......

我用一个成员创建了一个自定义限定符:

@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)and进行注释,则会@JobBinding(JOB_Y)收到有关重复注释的编译器错误。为了解决这个问题,我可以将注释的值更改为 JobTypes 数组,您可以像这样注释构建器

@JobBinding(JobType.JOB_X, JobType.JOB_Y)

使用省略号调用那里的构造函数来生成数组。但是,如果我这样做了,我怎么能使用任何一个 jobTypes 以编程方式查找呢?Weld 文档建议您必须同时拥有两者;我需要提供确切的论点:

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 分别提供一个构建器类,只要一个就足够了。有任何想法吗?提前致谢!

4

1 回答 1

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;
    }    
}

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

它应该做“工作”。

于 2011-10-22T02:05:40.150 回答