SMART deployで独自の個別パッケージを追加する
いま、関わってるプロジェクトで、バッチ処理の実装がありまして、当初S2Quartzとかで起動するようになってたのですが、運用要件的にスペック不足と言うことでアーキテクチャを改めることになりました。
でまあ、いろいろ検討した結果、JMX経由で外から叩くということになり、改めてバッチジョブの実装を確認しました。すると、SMART deployの対象から外れている人たちなので、残念ながらServiceなどのインジェクションが行われず、S2Container#getComponentでServiceを取得するような実装となっていました。当然、他のパッケージのクラス(teedaを使ってますのでPageクラスとか)と比べると、どうしても冗長な実装と言わざるをえません。
そこで、「これらのジョブクラスがSMART deployされるようになれば、いい感じばい」と思い、試してみました。作るのはjobパッケージです。
基本的には、「SMART deployに対応させてみる - じゅんいち☆かとうの技術日誌」を参考にしてます。
まずは、jobパッケージCreatorの実装。こんな感じ。
import org.seasar.framework.container.ComponentCustomizer; import org.seasar.framework.container.creator.ComponentCreatorImpl; import org.seasar.framework.container.deployer.InstanceDefFactory; import org.seasar.framework.convention.NamingConvention; public class JobCreator extends ComponentCreatorImpl { private static final String NAME_SUFFIX_JOB = "Job"; public JobCreator(NamingConvention namingConvention) { super(namingConvention); setNameSuffix(NAME_SUFFIX_JOB); setInstanceDef(InstanceDefFactory.PROTOTYPE); setExternalBinding(false); setEnableAbstract(false); setEnableInterface(false); } public ComponentCustomizer getHelperCustomizer() { return getCustomizer(); } public void setHelperCustomizer(ComponentCustomizer customizer) { setCustomizer(customizer); } }
それでもって、creator.diconにこのJobCreatorを追加します。
<?xml version="1.0" encoding="Shift_JIS"?> <!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN" "http://www.seasar.org/dtd/components21.dtd"> <components> <include path="convention.dicon"/> <include path="customizer.dicon"/> <component class="org.seasar.framework.container.creator.PageCreator"/> <component class="org.seasar.framework.container.creator.ActionCreator"/> <component class="org.seasar.framework.container.creator.DaoCreator"/> <component class="org.seasar.framework.container.creator.DtoCreator"/> <component class="org.seasar.framework.container.creator.DxoCreator"/> <component class="org.seasar.framework.container.creator.HelperCreator"/> <component class="org.seasar.framework.container.creator.LogicCreator"/> <component class="org.seasar.framework.container.creator.ServiceCreator"/> <component class="org.seasar.framework.container.creator.InterceptorCreator"/> <component class="org.seasar.framework.container.creator.ValidatorCreator"/> <component class="org.seasar.framework.container.creator.ConverterCreator"/> <component class="foo.job.JobCreator"/> </components>
あとは、必要に応じてcustomizer.diconを変更します。とりあえずはTraceInterceptorのみ追加します。
<?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="default-customizer.dicon"/> ..... <component name="jobCustomizer" class="org.seasar.framework.container.customizer.CustomizerChain"> <initMethod name="addCustomizer"> <arg>traceCustomizer</arg> </initMethod> </component> </components>
これで、以下のような、jobパッケージ以下の「〜Job」クラスはSMART deployの対象となり、@BindingアノテーションでのServiceの実装クラスのインジェクションなども効くようになります。
package foo.job; import foo.service.HogeService; import org.seasar.framework.container.annotation.tiger.Binding; import org.seasar.extension.datasource.DataSourceFactory; public abstract class HogeJob { @Binding private HogeService hogeService; @Binding private DataSourceFactory dataSourceFactory; // ジョブの本体 public void execute() { dataSourceFactory.setSelectableDataSourceName("test"); hogeService.fuga(); } }
ご覧の通り、非常にシンプルな感じとなり、実装メンバーにもなかなか好評でした。
問題点としては、Hot Deployに対応していないと言うことですが、今のプロジェクトはクラス数もかなり多く、Cool Deployが主流なのでまあいいかなと。
JMX経由でのジョブのキックの話題についてはまた今度。