javax.enterprise.inject.Instance についてメモ。
環境
Weld
1.1.10
実装
カスタム限定子
MyQualifier.java
package cdi.instance;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Qualifier;
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyQualifier {
}
インターフェースとその実装クラス
MyInterface.java
package cdi.instance;
public interface MyInterface {
void execute();
}
Hoge.java
package cdi.instance;
public class Hoge implements MyInterface {
@Override
public void execute() {
System.out.println("hoge");
}
}
Fuga.java
package cdi.instance;
@MyQualifier
public class Fuga implements MyInterface {
@Override
public void execute() {
System.out.println("fuga");
}
}
実行用クラス
Main.java
package cdi.instance;
import javax.enterprise.inject.Any;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;
import org.jboss.weld.environment.se.Weld;
import org.jboss.weld.environment.se.WeldContainer;
public class Main {
public static void main(String[] args) {
Weld weld = new Weld();
WeldContainer container = weld.initialize();
Main main = container.instance().select(Main.class).get();
main.execute();
weld.shutdown();
}
@Inject @Any Instance<MyInterface> instanceWithAny;
@Inject Instance<MyInterface> instanceWithOutAny;
public void execute() {
MyInterface obj;
// @Any あり
obj = instanceWithAny.select(Hoge.class).get();
obj.execute();
obj = instanceWithAny.select(Fuga.class).get();
obj.execute();
// @Any なし
obj = instanceWithOutAny.select(Hoge.class).get();
obj.execute();
obj = instanceWithOutAny.select(Fuga.class).get();
obj.execute();
}
}
実行結果
実行結果
hoge
fuga
hoge
Exception in thread "main" org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001308 Unable to resolve any beans for Types: [class cdi.instance.Fuga]; Bindings: [QualifierInstance{annotationClass=interface javax.enterprise.inject.Default, values={}, hashCode=974519704}]
at org.jboss.weld.manager.BeanManagerImpl.getBean(BeanManagerImpl.java:699)
at org.jboss.weld.bean.builtin.InstanceImpl.get(InstanceImpl.java:102)
at cdi.instance.Main.execute(Main.java:39)
at cdi.instance.Main.main(Main.java:17)
説明
javax.enterprise.inject.Instance
とは、型引数で指定したクラスを継承したクラスのインスタンスを CDI のコンテナから取得するための API 的なもの。
@Inject Instance<MyInterface> instance;
上記の場合は、 MyInterface
を継承したクラスのインスタンスを、 instance
から取得できる。
@Any について
@Anyのありなしについて
@Inject @Any Instance<MyInterface> instanceWithAny;
@Inject Instance<MyInterface> instanceWithOutAny;
@Any
は、カスタム限定子を設定したクラスも抽出対象にするかどうかを制御するためのもの。
@Any
が付いている場合は、カスタム限定子が付与されているクラスも抽出対象になる。
一方、 @Any
が付いていない場合は、カスタム限定子を付与したクラスは抽出対象外になり、無理に取得しようとすると例外がスローされる。