ksino's diary

覚えたことを忘れないように、小さなことでも書いていく。

CDIビーンを動的に取得する

やりたいこと

CDIビーンを動的に取得したい。
動的という表現も微妙ですが、要は@Injectでなくプログラム的に取得したいということです。

実装コード

CDIビーン

インタフェース
package jp.gr.java_conf.ksino.weldtest.cdibeans;

public interface Hero {
    public void showName();
}
実装クラス
package jp.gr.java_conf.ksino.weldtest.cdibeans;

import jp.gr.java_conf.ksino.weldtest.annotation.SupermanQualifier;

@SupermanQualifier
public class Superman implements Hero {
    @Override
    public void showName() {
        System.out.println("スーパーマン");
    }
}

CDI限定子

package jp.gr.java_conf.ksino.weldtest.annotation;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Target;
import javax.inject.Qualifier;

@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface SupermanQualifier {
    
}

CDI限定子(アノテーション)のインスタンスを取得するための実装クラス

これを作るのがミソです。後述するAPIを利用するために必要になります。

package jp.gr.java_conf.ksino.weldtest.annotation;

import javax.enterprise.util.AnnotationLiteral;

public class SupermanQualifierImpl 
    extends AnnotationLiteral<SupermanQualifier> {
}

CDIビーンを動的に取得

package jp.gr.java_conf.ksino.weldtest.logic;

import javax.enterprise.inject.Instance;
import javax.enterprise.inject.spi.CDI;
import jp.gr.java_conf.ksino.weldtest.annotation.SupermanQualifierImpl;
import jp.gr.java_conf.ksino.weldtest.cdibeans.Hero;

public class Logic {
    public void call() {
        CDI<Object> current = CDI.current();
        // ここでアノテーションのインスタンスが必要になる
        Instance<Hero> select =
            current.select(Hero.class, new SupermanQualifierImpl());
        Hero hero = select.get();
        hero.showName();
    }
}

実行コード

以下の記事と同じです。
ksino.hatenablog.com