稚北の授業用にSpringframeworkのapplicationContext.xmlをGroovyで代替するためのプラグインコードを書いてみました。サンプルなので実装はイマイチなのですが面白いと思うのでエントリしておきます。
スクリプトをどこに利用するのか、という点で僕が期待しているのが設定ファイルの代替です。SOAでも明らかなように設定ファイルの重要性が高まっています。その中でXMLという"言語"では限界があることを感じています。いかにダイヤグラム化できるという優位性があっても、複雑な分岐やループをタグの意味に織り込むには限界があります。そこでXMLのように構造表現が可能でありながら、多彩な処理を記述できるスクリプト言語が設定ファイルを記述するのに向いていると思っています。
これはDSLという文脈で考えてもいいでしょう。設定ファイルのDSL化ですね。
さて、サンプルのWARファイルです(ソースコード込み)。ダウンロードしてデプロイしてください。Tomcatであればwebapps配下に置くだけ。起動してindex.jspにアクセスすると、ぱらぱらと文字列が表示されます。なお、springframeworkの2.0 rc3を利用しています。
まず、元になるapplicationContext.xmlです。日付(java.util.Date)。次にビジネスロジックとDAOを組み合わせています。で、文字列を4つ。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="date" class="java.util.Date" />
<bean id="dao" class="jp.arclamp.sample.SampleDaoDummy" />
<bean id="dummydao" class="jp.arclamp.sample.SampleDaoImpl" />
<bean id="bl" class="jp.arclamp.sample.BusinessLogicImpl">
<property name="sampleDao"><ref bean="dao" /></property>
</bean>
<bean id="strA" class="java.lang.String">
<constructor-arg>
<value>A</value>
</constructor-arg>
</bean>
<bean id="strB" class="java.lang.String">
<constructor-arg>
<value>B</value>
</constructor-arg>
</bean>
<bean id="strC" class="java.lang.String">
<constructor-arg>
<value>C</value>
</constructor-arg>
</bean>
<bean id="strD" class="java.lang.String">
<constructor-arg>
<value>D</value>
</constructor-arg>
</bean>
</beans>
これを、Groovyを使って表現してみます。applicationContext.groovyを見てください。なお、ダウンロードされるサンプルでは、web.xmlのcontextClassが指定されているため、このファイルが処理されています。逆にcontextClassを消してもらうと、通常のapplicationContext.xmlが読み込まれるようになっています。
import org.springframework.beans.factory.config.RuntimeBeanReference
import org.springframework.beans.PropertyValue
import jp.arclamp.sample.*
def list = ["A","B","C","D"]
def builder = new jp.arclamp.springframework.util.SpringBuilder(appContext);
builder.beans(){
bean(id:'date', class:java.util.Date.class)
if ( appContext.servletContext.getInitParameter('mode') == 'test' ) {
bean(id:'dao', class:SampleDaoDummy.class)
} else {
bean(id:'dao', class:SampleDaoImpl.class)
}
bean(id:'bl', class:BusinessLogicImpl.class) {
ref(name:'sampleDao', bean:'dao')
}
list.each() { v ->
bean(id:'str'+v, class:java.lang.String.class){
constructor(v)
}
}
}
Groovyの特徴的な機能であるBuilderを使っています。なんとなく分かるとは思いますが、階層化したbeanやrefというのがタグにあたります。Groovyの機能を使っているのは2箇所。
まず、1つ目はIF文によるDAO実装の切り替えしています。これはweb.xmlに指定されたcontext-paramのmodeがtestの場合だけダミーの実装にします。web.xmlの該当箇所を変えて再起動すると表示される字が変わることで確認できます。
2つ目はループ処理で同じようなコンポーネントを登録していること。クロージャーを使うことによってさっくりと定義しています。
見ていただいていかがでしょうか?構造表現がされておりながらIFやループが使われています。分かりやすい、、、とは言いませんが(w、僕自身は可能性を感じています。
実装に当たっては Groovy killed the XML file?のコードを参考にさせてもらいました。Groovy専用のApplicationContextを作成しapplicationContext.groovyを処理するようにするとともに、SpringBuilderによってSpringframeworkへの設定を処理しています。
実装はいい加減なので、現在のサンプル程度のタグしか用意されていません(bean、property、constructor、ref)。あくまでもお遊びということで。あ、ビルドファイルもGroovyで書いてあります。なにか質問かフィードバックがあれば、よろしくお願いします。

コメント (2)
こんにちわ。
>スクリプトをどこに利用するのか、という点で僕が期待しているのが設定ファイルの代替です。
そうそう!と思います。Springに適応してしまうところは流石ですね。
以前「WebLogicのコンフィグレーションにGroovyを使う」なんてことが一瞬盛り上がってました。今探してみると、見つけられないですけど・・。いいアプローチだと思ったんですけどね。
最近の事情はわからないのですが、BPELなんかの代替にはならないのでしょうか。
投稿者: takeda | 2006年09月13日 01:09
日時: 2006年09月13日 01:09
BPEL仕様のスクリプト言語を考えればいいとは思うのですが。そのサンプル実装もつくりたいのですが、なかなか良いアイデアが浮かばずといったところです。
投稿者: yusuke | 2006年09月14日 11:06
日時: 2006年09月14日 11:06