Seasar2.3でいろいろと自動的な

んで、今日はJTA関連ではなくて、Seasar2.3からあるけれども実際に私は使ったことのなかった「コンポーネントの自動登録」や「アスペクトの自動登録」を体験してみましたので、メモっとこうってことです。
http://s2container.seasar.org/2.4/ja/DIContainer.html#ComponentAutoRegister
http://s2container.seasar.org/2.4/ja/DIContainer.html#AspectAutoRegister

で、

Seasar入門 はじめてのDI&AOP

Seasar入門 はじめてのDI&AOP

  • 作者: 須賀幸次,木村聡,西川麗,高安厚思,白井博章,椎野峻輔,岡薫,藤村浩士,ひがやすを
  • 出版社/メーカー: ソフトバンククリエイティブ
  • 発売日: 2006/02/25
  • メディア: 大型本
  • 購入: 7人 クリック: 51回
  • この商品を含むブログ (67件) を見る

この本。今までも大変参考にさせていいただいております。とてもいい本です。この本の4章のサンプルプログラムを使って試してみました。


まず、元のサンプルのSampleTransaction.diconと

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.3//EN"
	"http://www.seasar.org/dtd/components23.dtd">
<components>
	<include path="j2ee.dicon" />
	<component class="sample.transaction.EmployeeDaoImpl" />
	<component class="sample.transaction.SampleTransactionImpl">
		<aspect>j2ee.requiredTx</aspect>
	</component>
</components>


J2ee.dicon

<?xml version="1.0" encoding="Shift_JIS"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container//EN"
"http://www.seasar.org/dtd/components.dtd">
<components namespace="j2ee">
	<component name="transactionManager"
		class="org.seasar.extension.jta.TransactionManagerImpl"/>
	<component name="requiredTx"
		class="org.seasar.extension.tx.RequiredInterceptor"/>
	<component name="requiresNewTx"
		class="org.seasar.extension.tx.RequiresNewInterceptor"/>
	<component name="mandatoryTx"
		class="org.seasar.extension.tx.MandatoryInterceptor"/>

	<!--	XADataSource コンポーネント	-->
	<component name="xaDataSource"
		class="org.seasar.extension.dbcp.impl.XADataSourceImpl">
		<property name="driverClassName">
			"org.postgresql.Driver"
		</property>
		<property name="URL">
			"jdbc:postgresql://localhost:5432/neko"
		</property>
		<property name="user">"neko"</property>
		<property name="password">""</property>
	</component>

	<!--	connectionPool コンポーネント	-->
	<component name="connectionPool"
		class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl">
		<property name="timeout">600</property>
		<property name="maxPoolSize">10</property>
		<destroyMethod name="close"/>
	</component>


	<!--	Datasouece コンポーネント	-->
	<component name="dataSource"
		class="org.seasar.extension.dbcp.impl.DataSourceImpl"/>
</components>


SampleTransactionImpl

public class SampleTransactionImpl implements SampleTransaction {

	private EmployeeDao dao_;

	public SampleTransactionImpl(EmployeeDao dao) {
		dao_ = dao;
	}
    〜以下略〜


EmployeeDaoImpl

public class EmployeeDaoImpl implements EmployeeDao {

	private DataSource dataSource_;

	public EmployeeDaoImpl(DataSource dataSource){
		dataSource_ = dataSource;
	}
    〜以下略〜

これでビジネスロジックにあたる、SampleTransactionImplには、自動インジェクションで、Daoの実装がセットされる。Daoの実装にはこれも自動インジェクションでj2ee.diconのDataSourceImplがセットされる。


書き換えたSampleTransaction.dicon

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

   <component class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
    <initMethod name="addClassPattern">
            <arg>"sample.transaction.business.Impl"</arg>
            <arg>".*"</arg>
        </initMethod>
   </component>
   
   <component class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
    <initMethod name="addClassPattern">
            <arg>"sample.transaction.dao.Impl"</arg>
            <arg>".*"</arg>
        </initMethod>
   </component>

   <component class="org.seasar.framework.container.autoregister.AspectAutoRegister">
    	    <property name="interceptor">j2ee.requiredTx</property>
    	    <!--<property name="pointcut">"logicCommit"</property>-->
    	    <initMethod name="addClassPattern">
		 <arg>"sample.transaction.business.Impl"</arg>
		 <arg>".*"</arg>
	    </initMethod>
   </component>

</components>

ずいぶん長くなったとお感じでしょうが、上の2つのコンポーネントコンポーネントの自動登録で、下の1つがアスペクトの自動登録。なにがどうなるかっていうと、タグを明示的に記載しなくても"sample.transaction.business.Impl"パッケージの".*"(つまりすべてのクラス:正規表現で指定)はコンテナに自動的に登録してくれる。


ここではたったの1つずつのクラスしかないから、かえって記述が長くなってしまっているますが、これから先、どんなにビジネスロジックやDaoが増えたとしてもこの規約に従って、このパッケージ内にクラスを作ってあげれば、自動的にコンテナに登録されるって寸法っす。


もとのクラスたちはsample.transactionパッケージの直下にすべて入れて動かしてたんですが、自動登録に際してsample.transactionの下に"sample.transaction.business""sample.transaction.business.Impl""sample.transaction.dao""sample.transaction.dao.Impl"を作成しています。


はじめ"sample.transaction.business""sample.transaction.dao"をつくって、その中にインターフェイスとその実装をいれてやってみたら、なんか二つ同じ名前で登録されるので、だめなんだよアホが的なエラーになって、上のサイトよく見てみるとこんな記述がありました・・・

org.seasar.framework.container.autoregister.DefaultAutoNaming

クラスの完全修飾名からパッケージ部分を除き、最後がImplまたはBeanで終わっていたら削除し、 
先頭を小文字にした名前をコンポーネントの名前に設定します。 例えば、aaa.HogeImplクラスの場合、
コンポーネント名は、hogeになります。


設定は明示的にしていませんが、FileSystemComponentAutoRegisterには、

public abstract class AbstractComponentAutoRegister extends AbstractAutoRegister implements ClassHandler {

    protected static final String CLASS_SUFFIX = ".class";
    
    private AutoNaming autoNaming = new DefaultAutoNaming();
    
    private InstanceDef instanceDef;
  
  〜以下略〜

を見てもわかるように、DefaultAutoNamingが設定されるので、SampleTransactionとSampleTransactionImplが同じ「sampleTransaction」という名前で登録されることになってしまい、エラーが発生したってことみたいですね。
3つ目のコンポーネント登録はAspectの自動登録機能で、ここでは、j2ee.requiredTxのインターセプタを"sample.transaction.business.Impl"パッケージのすべてのクラスに適用している。詳しい設定はこちら
こういう機能があるわけですね。2.4の機能かと思ってました。というのも、2.4にはSmartDeployって機能があって、その辺と一緒くたになっていたと言ったところでしょうか?
2.3やってて、2.4みるとCustomizerとかConvensionとかCreatorとかあって面食らいますが、ようやく頭の中の整理がついてきました。今度はSmartDeployで、このサンプルを動かしてみることにします。