CDIでアノテーション使わないBean取得方法
CDIで@Injectアノテーションを使わずに、名前(文字列)でBeanを取得するにはどうするんだろうかとちょっと気になったので調べてみた。
Bean
@Injectの時だとスコープだけ書いてあげたらインジェクションされるけど、名前で引くときは@Named付けないとダメっぽい。名前で引こうってんだからまぁ当然と言えば当然か。
@RequestScoped @Named public class Morning implements Greet { @Override public String say(String word) { return "good morning " + word; } }
BeanManager
CDI管理BeanはBeanManagerから取得できる。少しお作法がいるけれど、複雑なことやってなければお約束みたいな書き方っぽい。
@ApplicationPath("rs") @Path("hello") public class HelloResource extends Application { @Inject private BeanManager bm; @GET @Path("{word}") public String say(@PathParam("word") String word) { Set<Bean<?>> beans = bm.getBeans("morning"); Bean<?> bean = bm.resolve(beans); CreationalContext<?> cc = bm.createCreationalContext(bean); Greet greet = (Greet) bm.getReference(bean, Greet.class, cc); return greet.say(word); } }
BeanManager自体は@Injectで取得できる。
bm.getBeansで、Beanの名前を指定する。@Namedでvalueを未指定の場合はデフォルトで、クラス名の先頭小文字になる。指定してたらその名前。
何のSetなのか?とか、CreationalContextって何?とかはとりあえず気にせず、おまじないだと思っておくことにする。