Spring FrameworkのDIコンテナを利用して、バッチ処理の実行基盤を作成してみました。

目次

環境

  • JDK 12 (OpenJDK)
  • Apache Maven 3.6.1
  • Spring Framework 5.1.9.RELEASE

プロジェクトの作成

Mavenでプロジェクトを作成します。

mvn -B archetype:generate \
  -DgroupId=batch.di \
  -DartifactId=batch-with-spring-di-container

JDK12を使うため、作成されたプロジェクトのpom.xmlに以下のパラメーターを追加します。

<properties>
  <maven.compiler.source>12</maven.compiler.source>
  <maven.compiler.target>12</maven.compiler.target>
</properties>

依存関係の追加

pom.xmlを編集し、spring-contextを依存関係に追加します。

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>5.1.9.RELEASE</version>
</dependency>

バッチ処理クラスの作成

バッチ処理用のクラスを作成します。今回はサンプルなので、標準出力にメッセージを出すだけにしてます。

Repositoryクラス

DBアクセスに利用する想定のクラスです。

package batch.di.repository;

import org.springframework.stereotype.Repository;

@Repository
public class SampleRepository {
  public String find() {
    return "Hello world";
  }
}

Serviceクラス

業務ロジックを記述するクラスです。Repositoryクラスをインジェクションしてます。

package batch.di.service;

public interface Batch {
  void execute();
}
package batch.di.service;

import org.springframework.stereotype.Service;

import batch.di.repository.SampleRepository;

@Service
public class SampleBatch implements Batch {

  private SampleRepository sampleRepository;

  public SampleBatch(SampleRepository sampleRepository) {
    this.sampleRepository = sampleRepository;
  }

  @Override
  public void execute() {
    System.out.println(getClass().getSimpleName() + " start.");
    System.out.println(sampleRepository.getClass().getSimpleName() + ": " + sampleRepository.find());
    System.out.println(getClass().getSimpleName() + " end.");
  }
}

Configurationクラスの作成

DIコンテナ作成に使用するConfigurationクラスを作成します。作成したServiceクラスとRepositoryクラスをDIコンテナに登録するようコンポーネントスキャンします。

package batch.di;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan
public class BatchConfig {
}

実行クラスの作成

バッチ処理を実行するクラスを作成します。

package batch.di;

import org.springframework.beans.BeansException;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import batch.di.service.Batch;

public class BatchExecutor {
  public static void main (String[] args) {
    try (AnnotationConfigApplicationContext context = 
        new AnnotationConfigApplicationContext(BatchConfig.class);) {
      Batch batch = context.getBean(args[0], Batch.class);
      batch.execute();
    } catch (BeansException e) {
      System.err.println(e.getMessage());
    }
  }
}

jarファイルの作成

作成したJavaのクラスをjarファイルにまとめます。今回はスクリプトから実行するときに、依存ライブラリの指定を省けるようfat jarにします。

プラグインの追加

pom.xmlを編集し、Maven Assembly Pluginをプラグインに追加します。<mainClass />には、mainメソッドを持つクラスのFQCNを指定します。

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-assembly-plugin</artifactId>
      <version>3.1.1</version>
      <configuration>
        <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
        <archive>
          <manifest>
            <mainClass>batch.di.BatchExecutor</mainClass>
          </manifest>
        </archive>
      </configuration>
      <executions>
        <execution>
          <phase>package</phase>
          <goals>
            <goal>single</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

package

以下のコマンドを実行し、jarファイルを生成します。

mvn package

スクリプトの作成

作成したJavaのプログラムを実行するスクリプトを作成します。

#!/bin/sh
# jarファイルのパスは環境に応じて変更
JAR_FILE="target/batch-with-spring-di-container-1.0-SNAPSHOT-jar-with-dependencies.jar"

java -jar ${JAR_FILE} sampleBatch
RC=$?
if [[ ${RC} -ne 0 ]]; then
  echo "Failed to execute java program. Return code: ${RC}"
  exit 1
fi

exit 0

実行結果

作成したスクリプトを実行すると、コンソールに以下のように出力されます。Serviceクラスが実行され、Repositoryクラスがインジェクションされています。

SampleBatch start.
SampleRepository: Hello world
SampleBatch end.