2

Weld docs を読むと、これはできないと思いますが、実際にはできると思います。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 の 2 つがまったく同じ方法で組み込まれている場合はどうなるでしょうか。これらのオプション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();

配列を使用すると、検索時に一致する必要がある値が実際に変更されます。同じ修飾子アノテーションでクラスに 2 回アノテーションを付け、それらの任意の組み合わせでそれを検索できる方法が本当に必要です。それ以外の場合は、X と Y のそれぞれにビルダー クラスを提供する必要があります。何か案は?前もって感謝します!

4

1 に答える 1

2

コメントで述べたように、Bean クラスに 2 つ以上の修飾子がある場合、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 に独自の修飾子と@NewBean の新しいインスタンスを作成する修飾子を挿入して、スコープの問題を回避します (詳細については、Weld のドキュメントを参照してください)。

それは「仕事」をするべきです。

于 2011-10-22T02:05:40.150 に答える