ライターで静的変数を使用し、ステップ コンテキスト/ジョブ コンテキストを使用して、ステップ リスナーの afterStep() で取得することを考えていました。しかし、試してみるとnullになりました。
この時点でItemWriterはすでに破棄されている可能性がありますが、わかりません。
これは正しい方法ですか?
はい、それで十分です。ただし、バッチ ランタイムはパーティションごとにStepContextクローンを維持するため、すべてのパーティションで合計行数が共有されるようにする必要があります。むしろ使用する必要がありますJobContext
。
PartitionCollectorとPartitionAnalyzerを使用することも良い選択だと思います。インターフェイスPartitionCollectorcollectPartitionData()
には、そのパーティションからのデータを収集するメソッドがあります。収集されると、バッチ ランタイムはこのデータをPartitionAnalyzerに渡してデータを分析します。があることに注意してください
- ステップごとに N PartitionCollector (パーティションごとに 1 つ)
- ステップごとの N StepContext (パーティションごとに 1)
- ステップごとに 1 つの PartitionAnalyzer
書き込まれたレコードは、 StepContextのを介して渡すことができますtransientUserData
。StepContextは独自のステップ パーティション用に予約されているため、一時的なユーザー データが他のパーティションによって上書きされることはありません。
実装は次のとおりです。
MyItemWriter :
@Inject
private StepContext stepContext;
@Override
public void writeItems(List<Object> items) throws Exception {
// ...
Object userData = stepContext.getTransientUserData();
stepContext.setTransientUserData(partRowCount);
}
MyPartitionCollector
@Inject
private StepContext stepContext;
@Override
public Serializable collectPartitionData() throws Exception {
// get transient user data
Object userData = stepContext.getTransientUserData();
int partRowCount = userData != null ? (int) userData : 0;
return partRowCount;
}
MyPartitionAnalyzer
private int rowCount = 0;
@Override
public void analyzeCollectorData(Serializable fromCollector) throws Exception {
rowCount += (int) fromCollector;
System.out.printf("%d rows processed (all partitions).%n", rowCount);
}
参考:JSR352 v1.0 Final Release.pdf