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
で、
- 作者: 須賀幸次,木村聡,西川麗,高安厚思,白井博章,椎野峻輔,岡薫,藤村浩士,ひがやすを
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 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つがアスペクトの自動登録。なにがどうなるかっていうと、
ここではたったの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で、このサンプルを動かしてみることにします。