hatenob

プログラムって分からないことだらけ

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って何?とかはとりあえず気にせず、おまじないだと思っておくことにする。