前回は、コンフィグとしてのDIコンテナというのを書きました。DIコンテナでアプリケーション構成を記述することが、これまでの設定ファイルの記述とは次元の違う、アプリケーション構成のコンフィグであるというのはお分かりいただけたと思います。
ですが、そうして記述されるDIコンテナの定義ファイルは読みにくいものでした。そこにナイスアイデアで切り込んだのがxbeanです。
xbeanは、何度か紹介していますが、ようは名前空間を使って複数のスキーマを1つの定義ファイルに書きましょうというものです。SpringFrameworkでは1.2.1からサポートされています。ですから長ったらしい定義ファイルも簡単に記述することができます。まず、こんなファイルがあるとします。
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="workflowManager" class="flow.impl.WorkflowManagerImpl">
<property name="workflows">
<list>
<bean class="flow.impl.WorkflowImpl">
<property name="title" value="DocumentManagement" />
<property name="states">
<list>
<bean class="flow.impl.StateImpl">
<property name="title" value="Editing" />
<property name="activities">
<list>
<bean class="flow.impl.ActivityImpl">
<property name="title" value="Edit" />
<property name="action" ref="editAction" />
<property name="condition" ref="editCondition" />
</bean>
<bean class="flow.impl.ActivityImpl">
<property name="title" value="Apply" />
<property name="action" ref="applyAction" />
<property name="condition" ref="applyCondition" />
</bean>
</list>
</property>
</bean>
</list>
</property>
</bean>
</list>
</property>
</bean>
<bean id="editAction" class="sample.EditAction" />
<bean id="editCondition" class="sample.EditCondition" />
<bean id="applyAction" class="sample.ApplyAction" />
<bean id="applyCondition" class="sample.ApplyCondition" />
</beans>
まずクラスflow.WorkflowManagerそのものをworkflowManagerで登録します。そいつの属性flowsは java.util.Listになっており複数のフローを登録できます。ここでは実体としてクラス flow.Flowを属性titleがDocumentManagementとしてを定義しています。クラスflow.Flowには属性statesがあり、これがまたjava.util.Listになっています。登録されているのは実体がクラスflow.Stateで属性titleがEditing。そしてクラスflow.Stateには属性activitiesがあり、これまたjava.util.List。登録されているのは実体がクラスflow.Activityで属性titleがEditとApply。さらにクラス flow.Activityには、属性actionと属性conditionがあります。書かれていませんが、それぞれインタフェース flow.Actionとインターフェースflow.Conditionを取ります。
これをxbean(xbean 2.2で試しました)で書いてみましょう。まず、スキーマの設定をしなくてはいけません。xmlns:f="http://flow/schemas/flow"という名前空間にします。で、これに対応するようにMETA-INF/services/org/xbean/spring/http/flow/schemas/flowというファイルを作成します。中身はこんな感じ。
workflowManager = flow.impl.WorkflowManagerImpl
workflowManager.list.workflow = workflows
workflow = flow.impl.WorkflowImpl
workflow.list.state = states
state = flow.impl.StateImpl
state.list.activity = activities
activity = flow.impl.ActivityImpl
.list.というのが<list>を持っている属性名として定義されています。これを元に設定ファイルを書くとこうなります。
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans xmlns:f="http://flow/schemas/flow">
<f:workflowManager id="workflowManager">
<f:workflows>
<f:workflow title="DocumentManagement">
<f:states>
<f:state title="Editing">
<f:activities>
<f:activity title="Edit" action="#editAction"
condition="#editCondition" />
<f:activity title="Apply" action="#applyAction"
condition="#applyCondition" />
</f:activities>
</f:state>
</f:states>
</f:workflow>
</f:workflows>
</f:workflowManager>
<bean id="editAction" class="sample.EditAction" />
<bean id="editCondition" class="sample.EditCondition" />
<bean id="applyAction" class="sample.ApplyAction" />
<bean id="applyCondition" class="sample.ApplyCondition" />
</beans>
#が付いているのはrefという意味になります。
どうでしょうか。設定ファイルが短かくなるだけでなく、すごく分かりやすいことに気付きます。そう、Digesterで定義したものにイメージが近くなります。
なお、コードはこちらからダウンロードできるようにしました。Eclipseのプロジェクトになっているので、解凍してインポートするなり、ワークスペースに置くなりしてください。あとはテストコードを実行するだけです。
そもそも設定ファイルのスキーマというのは、そのアプリケーションが持っている思想と深く結びついているものです。思想が現れるのがスキーマといっても過言ではありません(参照:枠組みのワクグミを見抜こう)。ですから、スキーマというのは変えがたく、そしてアプリケーション間では相容れないものとなります。
そこで標準仕様を用意してベンダー間で調整を行なったりします。が、もちろんの事、各社各様の思想を持ち寄るわけで、結果として最小公倍数的なわけわかんないスキーマができあがったりします。UMLとか、ws-*とか、EJBとか、最近ではJBIとかBPELとか、あげればキリがありません。特徴は誰も読めない分厚い仕様書(除く丸山先生)。
でも、xbeanは正反対のアプローチを取りました。いいじゃん違うスキーマで、と。
Springの設定ファイルはアプリケーション構成をしめす、ごくごく汎用的なタグで定義されています。xbeanはラッパーに過ぎません。
つまりxbeanは「アプリケーションの思想=スキーマ」を「汎用的なアプリケーション構成」に変換しているわけです。
ですから、xbeanが「ある意味、究極の統一定義」として機能する可能性があります。
例えばStrutsやHibernateがDIコンテナで定義できるようになっていれば、xbean が利用可能なはずです(現状のxbeanでは機能不足ですが)。となると、1つの設定ファイルの中にStrutsとHibernateの設定も書けるということを示します。StrutsやHibernateだって、ようはアプリケーション構成なんだから、できて当然でしょう。
こうやって設定ファイルを記述する世界から、アプリケーション構成そのものを設定する世界にシフトすると、また違った可能性が見えてくるのではないかと感じています。
なお、xbeanはCodeHausからApache Geronimoプロジェクトに移籍中です。Geronimoは複数のコンポーネントを組み合わせて1つのアプリケーション・サーバを構築しようとしていますから、このxbeanのアイデアはぴったりです。というか元々Geronimoの設定ファイルの複雑さをキッカケにしてxbeanが作られたので、いわゆる出戻りですね。
次回は、ちょっと視点を変えてコンテナに注目してみます。SCAやJBIがなぜコンテナやコンポーネント、モジュールという単位を重視しているのでしょうか?
