@Producesを使って動的に生成するクラスを切り替える
次に、動的に生成クラスを切り替える方法です。前回紹介したサイコロの例では、限定子を使って生成されるクラスを切り替えました。限定子をつけるだけで簡単にクラスを変更できたのですが、限定子をハードコーディングしていることから、クラスを動的に切り替えることはできないため、柔軟性に欠けます。そこで、@Producesを用いて動的に生成クラスを切り替える方法について学びます。
次の例は、@Producesを使って動的にサイコロを切り替えるコードです。
@Producesを使って動的にサイコロを切り替える Generator.java]
package sample.beans;
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.enterprise.inject.Produces;
import javax.inject.Named;
@SessionScoped …(1)
@Named("generator") …(1)
public class Generator implements Serializable {
private int diceType;
/**
* サイコロの種類を指定する
* @param value サイコロの種類を指定
*/
public void changeDice(int value) { …(2)
diceType = value;
}
@Dice
@Produces
public IDice getDice() { …(3)
IDice dice = null;
// diceTypeの値に応じて生成するインスタンスを切りかえる
switch (diceType) {
case 0:
// SimpleDiceを生成
dice = new SimpleDice();
break;
case 1:
// ExtendDiceを生成
dice = new ExtendDice();
break;
default:
}
return dice;
}
}
(1)GeneratorクラスがManagedBeanとして管理されます。@Namedでfaceletsから参照する時の名称、@SessionScopedでセッション単位で有効になります。
(2)サイコロの変更指示をメソッドの引数で管理します。diceTypeに値が格納されます。
(3)diceTypeの値に応じてサイコロのインスタンスを生成します。太字の部分にて限定子@Diceと@Producesを指定しているため、CDIコンテナはサイコロの取得処理をこのメソッドで行います。
これでサイコロの生成ロジックはこのGeneratorに移しましたので、前回作成したSimpleDiceとExtendDiceからは限定子@Diceを消去しておきます。
画面からは、ボタンでサイコロを切り替えるように変更します。
動的にサイコロを切り替える画面 index.xhtml]
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>乱数の取得</title>
</h:head>
<h:body style="font-size: 18px">
#{sample.message}から取得した値<br />
#{sample.nextValue()}
<h:form id="form1">
<h:commandButton id="simple"
value="通常のサイコロ" action="#{generator.changeDice(0)}" />
<h:commandButton id="extend"
value="大きな目のサイコロ" action="#{generator.changeDice(1)}" />
</h:form>
</h:body>
</html>
追加した箇所は、太字で示した送信フォーム<h:form>と、送信ボタンである<h:commandButton>です。<h:commandButton>のaction属性にて、GeneratorクラスのchangeDice()メソッドを呼び出し、サイコロの種類を指定します。
変更が完了したら、アプリケーションを起動してブラウザで稼働確認をしましょう。起動後は次のように通常のサイコロの結果が表示されます。

次に「大きな目のサイコロ」ボタンを押すと、大きな目のサイコロを振った結果とExtendDiceが実行されたことを示すメッセージが表示されました。

このように、CDIを使った依存性注入はとても手軽に使うことができ、簡単にカスタマイズして自由に依存性注入できることがご理解できたかと思います。
まとめ
以上、JavaEE6でアプリケーションを構築する方法と、CDIを使ったクラスの管理方法について紹介しました。アプリケーションを手軽に構築しながらクラス間の依存性を取り除き、変更に強いクラス構成が可能なことを理解していただければと思います。
