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経由でのジョブのキックの話題についてはまた今度。