S2Container 2.4.0 beta3でj2ee.diconがjarに組み込まれた件

2007/12/07追記:
ここに書いてある内容は、試行錯誤の結果です。実際に複数データソースを使うSeasar2.4でのやり方は、以下のFAQの方が分かりやすいです。
http://www.seasar.org/wiki/index.php?FAQ%2FS2DAO#w7da6e0e


 MLでも少し話題になりましたが、結構大きく変わった(ように見える)ので戸惑いがありますね。幸い(?)、まだ実業務で使ったことがないので、すぐには困りませんが(^^;

 ともあれ、私も今回の修正は少し気になってました。それは、複数のデータベース(あるいはデータベースユーザ)を使い分けたい時にどうすれば良いのか。Seasar WikiのFAQにはS2Container 2.3系までのやり方が書いてあります。

 2.4系でも基本的には同じ考え方で出来そうです。私が考えたのは、jdbc.diconをダミー(とコメントだけとか)にしておいて、接続先毎のdiconファイルを用意するという方法でした。

 で、漠然とそんなことを考えていたらt-wadaさんの日記(id:t-wada:20060620)で同じ内容を取り上げていたので、それも参考にやってみました。

 まずは、jdbc.diconをコピーして、jdbc01.diconとjdbc02.diconを作ります。内容はほとんど同じで接続先だけが違うという感じです。

jdbc01.diconサンプル

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
	"http://www.seasar.org/dtd/components21.dtd">
<components namespace="jdbc01">
	<include path="jta.dicon"/>

	<component class="org.seasar.extension.jdbc.impl.BasicResultSetFactory"/>
	<component class="org.seasar.extension.jdbc.impl.ConfigurableStatementFactory">
		<arg>
			<component class="org.seasar.extension.jdbc.impl.BasicStatementFactory"/>
		</arg>
		<property name="fetchSize">100</property>
	</component>

	<component name="xaDataSource"
		class="org.seasar.extension.dbcp.impl.XADataSourceImpl">
		<property name="driverClassName">
			"com.mysql.jdbc.Driver"
		</property>
		<property name="URL">
			"jdbc:mysql://127.0.0.1/test01"
		</property>
		<property name="user">"test01"</property>
		<property name="password">""</property>
	</component>

	<component name="connectionPool"
		class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl">
		<property name="timeout">600</property>
		<property name="maxPoolSize">10</property>
		<property name="allowLocalTx">true</property>
		<destroyMethod name="close"/>
	</component>

	<component name="DataSource01"
		class="org.seasar.extension.dbcp.impl.DataSourceImpl"
	/>

</components>

 そして、dao.diconも同じくdao01.diconとdao02.diconに分けます。

dao01.diconサンプル

<?xml version="1.0" encoding="Shift_JIS"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container//EN"
"http://www.seasar.org/dtd/components.dtd">
<components namespace="dao01">
	<include path="jdbc01.dicon"/>
	<include path="j2ee.dicon"/>
	<component
		class="org.seasar.dao.impl.FieldAnnotationReaderFactory"/>
	<component
		class="org.seasar.dao.impl.DaoMetaDataFactoryImpl"/>
	<component name="interceptor"
		class="org.seasar.dao.interceptors.S2DaoInterceptor"/>
	<component
		class="org.seasar.dao.impl.ValueTypeFactoryImpl"/>
</components>

 ここでのポイントは、上で作ったjdbc01.diconをj2ee.diconよりも先にincludeしているところです。

 そして、jdbc.diconも以下のような感じに修正します。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
	"http://www.seasar.org/dtd/components24.dtd">
<components>
	<include path="jdbc01.dicon"/>
	<include path="jdbc02.dicon"/>
</components>

 これで、dao01.intercepterを適用したDAOはtest01側へ、dao02.intercepterを適用したDAOはtest02側へ接続するようになります。

 なお、jdbc.diconにjdbc01.diconとjdbc02.diconをincludeするのは、@Resourceでも複数の接続先の使い分けを可能とするためです。@ResourceはEJB3の書き方だそうで、EJB3どころかJava 5さえもほとんどさわっていない私の認識は大きく間違っている可能性大ですが、以下のようなコードのためでしょうか。

@Resourceのサンプル

import javax.annotation.Resource;
import javax.sql.DataSource;

public class Test01 {

	@Resource(name = "jdbc/jdbc01/DataSource01")
	public DataSource ds;

	// ...以下省略

 これで、フィールドdsにtest01側のDataSourceがインジェクションされるようです。少し気になったのは、id:koichikさんが、jdbc/DataSourceという名前が使えそうに書かれていますが、ここはコンポーネント名になるので/は使えないと言う認識であっているのかどうか。試したところでは、jdbc÷DataSourceを実行しようとしているように見えましたが(^^;;直していただきました。