LoginSignup
7
7

More than 5 years have passed since last update.

CDIコンテナにSeasar2のコンポーネントを移す(その1)

Last updated at Posted at 2014-09-23

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の場合だと、ざっくり下記になります。

  1. S2Containerを初期化する
  2. JAX-RSを初期化する
  3. ResourceConfigの中で、S2ContainerのComponentDefを全て取り出す
  4. 取り出したComponentDefの内容をhk2のServiceLocatorに登録する

具体的なやり方

CDIコンテナにSeasar2のコンポーネントを移す (その2)

時間が無くなってきたので詳細また今度。。
スミマセン。。
7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7