ライターで静的変数を使用し、ステップ コンテキスト/ジョブ コンテキストを使用して、ステップ リスナーの 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