Job および Step 属性の遅延バインディング

前述の XML とフラットファイルの例では、どちらも Spring Resource 抽象化を使用してファイルを取得しています。Resource には java.io.File を返す getFile メソッドがあるため、これが機能します。標準の Spring コンストラクトを使用して、XML とフラットファイルの両方のリソースを構成できます。

  • Java

  • XML

次の例は、Java での遅延バインディングを示しています。

Java 構成
@Bean
public FlatFileItemReader flatFileItemReader() {
	FlatFileItemReader<Foo> reader = new FlatFileItemReaderBuilder<Foo>()
			.name("flatFileItemReader")
			.resource(new FileSystemResource("file://outputs/file.txt"))
			...
}

次の例は、XML での遅延バインディングを示しています。

XML 構成
<bean id="flatFileItemReader"
      class="org.springframework.batch.item.file.FlatFileItemReader">
    <property name="resource"
              value="file://outputs/file.txt" />
</bean>

上記の Resource は、指定されたファイルシステムの場所からファイルをロードします。絶対位置は二重スラッシュ (//) で始まる必要があることに注意してください。ほとんどの Spring アプリケーションでは、これらのリソースの名前はコンパイル時に認識されるため、このソリューションで十分です。ただし、バッチシナリオでは、ジョブのパラメーターとして実行時にファイル名を決定する必要がある場合があります。これは、-D パラメーターを使用してシステムプロパティを読み取ることで解決できます。

  • Java

  • XML

以下に、Java のプロパティからファイル名を読み取る方法を示します。

Java 構成
@Bean
public FlatFileItemReader flatFileItemReader(@Value("${input.file.name}") String name) {
	return new FlatFileItemReaderBuilder<Foo>()
			.name("flatFileItemReader")
			.resource(new FileSystemResource(name))
			...
}

次の例は、XML のプロパティからファイル名を読み取る方法を示しています。

XML 構成
<bean id="flatFileItemReader"
      class="org.springframework.batch.item.file.FlatFileItemReader">
    <property name="resource" value="${input.file.name}" />
</bean>

このソリューションが機能するために必要なのは、システム引数(-Dinput.file.name="file://outputs/file.txt" など)だけです。

ここで PropertyPlaceholderConfigurer を使用できますが、Spring の ResourceEditor はすでにフィルター処理を行い、システムプロパティでプレースホルダーの置換を行っているため、システムプロパティが常に設定されている場合は必要ありません。

多くの場合、バッチ設定では、(システムプロパティではなく) ジョブの JobParameters でファイル名をパラメーター化し、その方法でアクセスすることが望ましいです。これを実現するために、Spring Batch では、さまざまな Job および Step 属性の遅延バインディングが可能です。

  • Java

  • XML

次の例は、Java でファイル名をパラメーター化する方法を示しています。

Java 構成
@StepScope
@Bean
public FlatFileItemReader flatFileItemReader(@Value("#{jobParameters['input.file.name']}") String name) {
	return new FlatFileItemReaderBuilder<Foo>()
			.name("flatFileItemReader")
			.resource(new FileSystemResource(name))
			...
}

次の例は、XML でファイル名をパラメーター化する方法を示しています。

XML 構成
<bean id="flatFileItemReader" scope="step"
      class="org.springframework.batch.item.file.FlatFileItemReader">
    <property name="resource" value="#{jobParameters['input.file.name']}" />
</bean>

同じ方法で、JobExecution と StepExecution レベルの ExecutionContext の両方にアクセスできます。

  • Java

  • XML

次の例は、Java で ExecutionContext にアクセスする方法を示しています。

Java 構成
@StepScope
@Bean
public FlatFileItemReader flatFileItemReader(@Value("#{jobExecutionContext['input.file.name']}") String name) {
	return new FlatFileItemReaderBuilder<Foo>()
			.name("flatFileItemReader")
			.resource(new FileSystemResource(name))
			...
}
Java 構成
@StepScope
@Bean
public FlatFileItemReader flatFileItemReader(@Value("#{stepExecutionContext['input.file.name']}") String name) {
	return new FlatFileItemReaderBuilder<Foo>()
			.name("flatFileItemReader")
			.resource(new FileSystemResource(name))
			...
}

次の例は、XML で ExecutionContext にアクセスする方法を示しています。

XML 構成
<bean id="flatFileItemReader" scope="step"
      class="org.springframework.batch.item.file.FlatFileItemReader">
    <property name="resource" value="#{jobExecutionContext['input.file.name']}" />
</bean>
XML 構成
<bean id="flatFileItemReader" scope="step"
      class="org.springframework.batch.item.file.FlatFileItemReader">
    <property name="resource" value="#{stepExecutionContext['input.file.name']}" />
</bean>
遅延バインディングを使用する Bean は、scope="step" で宣言する必要があります。詳細については、ステップスコープを参照してください。Step Bean は、ステップスコープであってはなりません。ステップ定義でレイトバインディングが必要な場合は、そのステップのコンポーネント (タスクレット、アイテムリーダーまたはライターなど) を代わりにスコープする必要があります。
Spring 3.0 (またはそれ以上) を使用する場合、ステップスコープ Bean の式は、多くの興味深い機能を備えた強力な汎用言語である Spring 式言語にあります。後方互換性を提供するために、Spring Batch が古いバージョンの Spring の存在を検出した場合、強力ではなく、解析規則がわずかに異なるネイティブ式言語を使用します。主な違いは、上記の例のマップキーを Spring 2.5 で引用符で囲む必要がないことですが、Spring 3.0 では引用符が必須です。

ステップスコープ

前に示した遅延バインディングの例はすべて、Bean 定義で宣言された step のスコープを持っています。

  • Java

  • XML

次の例は、Java のステップスコープへのバインドの例を示しています。

Java 構成
@StepScope
@Bean
public FlatFileItemReader flatFileItemReader(@Value("#{jobParameters[input.file.name]}") String name) {
	return new FlatFileItemReaderBuilder<Foo>()
			.name("flatFileItemReader")
			.resource(new FileSystemResource(name))
			...
}

次の例は、XML でステップスコープにバインドする例を示しています。

XML 構成
<bean id="flatFileItemReader" scope="step"
      class="org.springframework.batch.item.file.FlatFileItemReader">
    <property name="resource" value="#{jobParameters[input.file.name]}" />
</bean>

遅延バインディングを使用するには、Step のスコープを使用する必要があります。Bean は、Step が開始されるまで実際にはインスタンス化されず、属性が検出されるためです。デフォルトでは Spring コンテナーの一部ではないため、batch 名前空間を使用するか、StepScope の Bean 定義を明示的に含めるか、@EnableBatchProcessing アノテーションを使用して、スコープを明示的に追加する必要があります。これらの方法の 1 つだけを使用してください。次の例では、batch 名前空間を使用しています。

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:batch="http://www.springframework.org/schema/batch"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="...">
<batch:job .../>
...
</beans>

次の例には、Bean 定義が明示的に含まれています。

<bean class="org.springframework.batch.core.scope.StepScope" />

業務範囲

Spring Batch 3.0 で導入された Job スコープは、構成が Step スコープに似ていますが、Job コンテキストのスコープであるため、実行中のジョブごとにそのような Bean のインスタンスが 1 つだけ存在します。さらに、#{..} プレースホルダーを使用して JobContext からアクセス可能な参照のレイトバインディングがサポートされます。この機能を使用すると、ジョブまたはジョブ実行コンテキストとジョブパラメーターから Bean プロパティを取得できます。

  • Java

  • XML

次の例は、Java でのジョブスコープへのバインドの例を示しています。

Java 構成
@JobScope
@Bean
public FlatFileItemReader flatFileItemReader(@Value("#{jobParameters[input]}") String name) {
	return new FlatFileItemReaderBuilder<Foo>()
			.name("flatFileItemReader")
			.resource(new FileSystemResource(name))
			...
}
Java 構成
@JobScope
@Bean
public FlatFileItemReader flatFileItemReader(@Value("#{jobExecutionContext['input.name']}") String name) {
	return new FlatFileItemReaderBuilder<Foo>()
			.name("flatFileItemReader")
			.resource(new FileSystemResource(name))
			...
}

次の例は、XML でジョブスコープにバインドする例を示しています。

XML 構成
<bean id="..." class="..." scope="job">
    <property name="name" value="#{jobParameters[input]}" />
</bean>
XML 構成
<bean id="..." class="..." scope="job">
    <property name="name" value="#{jobExecutionContext['input.name']}.txt" />
</bean>

デフォルトでは Spring コンテナーの一部ではないため、batch 名前空間を使用するか、JobScope の Bean 定義を明示的に含めるか、@EnableBatchProcessing アノテーションを使用して、スコープを明示的に追加する必要があります (アプローチを 1 つだけ選択してください)。次の例では、batch 名前空間を使用しています。

<beans xmlns="http://www.springframework.org/schema/beans"
		  xmlns:batch="http://www.springframework.org/schema/batch"
		  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		  xsi:schemaLocation="...">

<batch:job .../>
...
</beans>

次の例には、JobScope を明示的に定義する Bean が含まれています。

<bean class="org.springframework.batch.core.scope.JobScope" />
マルチスレッドまたはパーティション化されたステップでジョブスコープの Bean を使用することには、いくつかの実際的な制限があります。Spring Batch は、これらのユースケースで生成されたスレッドを制御しないため、そのような Bean を使用するように正しく設定することはできません。マルチスレッドまたはパーティション化されたステップでジョブスコープの Bean を使用することはお勧めしません。

ItemStream コンポーネントのスコーピング

Java 構成スタイルを使用してジョブまたはステップスコープの ItemStream Bean を定義する場合、Bean 定義メソッドの戻り値の型は少なくとも ItemStream である必要があります。これは、Spring Batch がこのインターフェースを実装するプロキシを正しく作成し、期待どおりに openupdateclose メソッドを呼び出すことによってその契約を尊重するために必要です。

次の例に示すように、そのような Bean の Bean 定義メソッドが最も具体的な既知の実装を返すようにすることをお勧めします。

最も具体的な戻り値の型でステップスコープの Bean を定義する
@Bean
@StepScope
public FlatFileItemReader flatFileItemReader(@Value("#{jobParameters['input.file.name']}") String name) {
	return new FlatFileItemReaderBuilder<Foo>()
			.resource(new FileSystemResource(name))
			// set other properties of the item reader
			.build();
}