JSFとCDIの連携

JavaEE6でJSFベースのWebアプリケーションを開発する場合JSFの管理BeanをCDIの管理Beanにしたほうがいいと思います。

CDIの管理Beanといっても特に何か特別なことをする必要はありません。

CDIを利用するにはWEB-INFディレクトリ配下にbeans.xmlファイルを作成します。

beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://docs.jboss.org/cdi/beans_1_0.xsd">
    
</beans>

特に内容を記述する必要はありません。このファイルがないとCDIを利用できないので利用する場合は必ず必要です。

次に前回作成したHelloActionをCDI管理Beanにします。

import java.io.Serializable;

import javax.enterprise.context.SessionScoped;
import javax.inject.Named;


@SessionScoped
@Named("hello")
public class HelloAction implements Serializable {
    .....
}

違いはSessionScopedアノテーションがjavax.enterprise.context.SessionScopedとなっていることと、@Namedアノテーションを利用していることです。
@Namedアノテーションを付与することでこのクラスをCDI管理Beanとすることができます。@Namedアノテーションに"hello"という文字列を設定していますが、これはView側のEL式で参照するためです。

たったこれだけです。再ディプロイして実行すると全く同じ結果が返ってくると思います。

それではもう一歩進んで、HelloActionをEJBにしてみたいと思います。JavaEE6ではEJBのバージョンが3.1となり、最大の特徴はwarファイル内で利用可能になったことです。

まずはインターフェースを以下のように定義します。

import javax.ejb.Local;

@Local
public interface Hello {

    public String sayHello();
    
    public String getName();

    public void setName(String name);

    public String getMessage();

    public void setMessage(String message);
}

普通のEJBのインターフェースです。次にHelloActionクラスを以下のように修正して完了です。

import javax.ejb.Stateful;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;

@SessionScoped
@Stateful
@Named("hello")
public class HelloAction implements Hello, Serializable {
    .....
}

ステートフルセッションBeanを表すアノテーション@Statefulと先ほど作成したインターフェースを実装しているだけで特に大きな違いはありません。

修正はこれだけです。実行すると全く同じ結果が返ってくると思います。

JavaEE6でJSFの管理BeanをCDIの管理Beanにする最大の利点はEJBがダイレクトで利用可能という点ではないでしょうか。CDIはもともとSeamの実装の一部をEE標準仕様に取り込んだものなのでやはりSeam色が強くStruts-Springユーザには馴染み辛いかもしれませんが、なれると抜群に生産性はいいと思います。