Java EE の CDI
Java EE 7 が登場してから JAX-RS や CDI (Contexts and Dependency Injection) など、便利なモノが用意されていますね。
JAX-RSはアノテーションによるコーディングが基本となっており、共通コンポーネントなどはCDIの@Injectで依存性を注入したり、その際にAOPで横断的な処理を追加できます。
S2コンテナのDI
ただ、Seasar2 の S2Container を利用して開発をしている方は、CDIを使おうとすると、
DIコンテナが2重管理となってしまい、なんだかコードが複雑化してきます。
では、DBアクセスにはS2JDBCを利用して、プレゼンテーション層にはJAX-RSを利用したい場合にどうするか。
JAX-RSとS2JDBCを組み合わせたい
例えば、JAX-RSのライブラリとして、Jerseyを利用した場合、SAStrutsでいうところのActionクラスは、Jerseyサーブレットによって生成されます。
SAStruts + S2JDBC の場合は、アクションの中に、@Bindingというアノテーションを書いておけば、ServiceクラスをDIする事ができました。
@Binding
protected CustomerService customerService;
しかし、Jerseyを利用した場合には、S2コンテナを通じてプレゼンテーション層のActionに相当するクラスが生成されないため、上記ではDIする事ができません。
そのため、やるとすれば下記のようなやりかたになります。
@Path("{id}")
public Customer getCustomer(@PathParam("id") String id) {
CustomerService customerService = SingletonS2Container.getComponent(CustomerService.class);
return customerService.findById(id);
}
S2JDBCのコンポーネントをCDIに移す
もし、JAX-RSと相性の良いCDIを利用することができたら下記のように修正できます。
@Inject
private CustomerService customerService;
@Path("{id}")
public Customer getCustomer(@PathParam("id") String id) {
return customerService.findById(id);
}
このようにすることでDIが一本化されます。
CDIの初期化
やり方はJerseyの場合だと、ざっくり下記になります。
- S2Containerを初期化する
- JAX-RSを初期化する
- ResourceConfigの中で、S2ContainerのComponentDefを全て取り出す
- 取り出したComponentDefの内容をhk2のServiceLocatorに登録する
具体的なやり方
CDIコンテナにSeasar2のコンポーネントを移す (その2)
スミマセン。。