Spring Batch 6 でパラメータを渡して起動

Spring Batch 6 のバッチ処理にパラメータ(ジョブ引数)を渡す方法。
例えばファイルパスなど、毎回違う値を渡すときに推奨されるやり方でコーディングしてみる。(reader や write などの Step で指定する(受け取る)やり方。今回は processor でジョブ引数を受け取るか形)

「Spring Batch 6 で Listener を追加してログを出す」で修正したバッチプログラムに修正を加える。(修正点のみ記述するので、全体のソースが見たい人は、元ネタのページを手繰ってくださいませ)

修正点は以下のとおり。

■import の追加

import org.springframework.batch.core.configuration.annotation.StepScope; //追加
import org.springframework.beans.factory.annotation.Value; //追加


■processor の修正

    @Bean
    @StepScope // ジョブ引数を受け取るために必須
    public ItemProcessor<UserCombinedDto, UserCombinedDto> processor(
                            @Value("#{jobParameters['models']}") Integer models,
                            @Value("#{jobParameters['modelName']}") String modelName) {
        return item -> {
            String phone = item.user_phone_number(); // DtoがRecordの場合のゲッター。通常のクラスなら .getUser_phone_number()

            // 電話番号が null でなく、かつ 090 または 080 で始まる場合
            if (phone != null && (phone.startsWith("090") || phone.startsWith("080"))) {
                // 表示名
                String displayName = "スマホ";
                // ジョブ引数をチェック
                if (models == null || "1".equals(models)) { // ジョブ引数未指定、あるいは models == 1
                    displayName = "携帯";
                }
                else {
                    if ("2".equals(models) && (modelName != null && !modelName.isEmpty())) {
                        // ジョブ引数 models = 2 で、modelName も指定されている
                        displayName = modelName;
                    }
                    else {
                        // ジョブ引数 models が 1でも 2でもない。または modelName が未指定
                        displayName = "未定義";
                    }
                }

                // 文字列を追加した新しいDtoを作成して返す
                // (DtoがRecordの場合はイミュータブル(不変)なので、このように新しくインスタンスを作る)
                return new UserCombinedDto(
                        item.user_id(),
                        item.user_name(),
                        item.user_address1(),
                        item.user_address2(),
                        phone + "(" + displayName + ")",
                        item.anniversary(),
                        item.note()
                );
            }

            // 条件に当てはまらない場合は、加工せずにそのまま次に渡す
            return item;
        };
    }

<修正ポイント>
  • メソッドに @StepScope アノテーションを必ず付与(このアノテーションを付けないとジョブ引数が受け取れない)
  • メソッドの引数に、受け取りたいジョブ引数を設定(例:@Value("#{jobParameters['modelName']}") String modelName)
  • 受け取ったジョブ引数で色々と処理(ジョブ引数は編集できないので、編集したいときは他の変数にコピー)


■Stepの定義の変更

    // 4. Stepの定義 (Spring Batch 6 スタイル)
    @Bean
    public Step exportStep (
                JdbcCursorItemReader<UserCombinedDto> reader,
                ItemProcessor<UserCombinedDto, UserCombinedDto> processor,
                FlatFileItemWriter<UserCombinedDto> writer) {
        return new StepBuilder("exportStep", jobRepository)
                .<UserCombinedDto, UserCombinedDto>chunk(100) // 100件ごとにコミット/出力
                .transactionManager(transactionManager)
                .reader(reader)       // 読んで
                .processor(processor) // 処理して
                .writer(writer)       // 書き出す
                .build();
    }

<修正ポイント>
メソッドの引数を。各Bean(Reader、Processor、Writer)の定義を受け取る形に設定
各 Step の呼び出しで引数指定は不要(例:.processor(processor()) →.processor(processor) )


■Jobの定義の変更

    // 5. Jobの定義
    @Bean
    public Job exportJob(Step exportStep) {
        return new JobBuilder("exportJob", jobRepository)
                .start(exportStep)
                .listener(jobListener) // JobExecutionListenerを追加
                .build();
    }

<修正ポイント>
メソッドの引数を、exportStep の定義を受け取る形に設定
exportStep を呼び出すときの引数を不要に(例:.start(exportStep())→.start(exportStep))

Spring Framework は「@Bean アノテーションの付いたメソッドの引数に他の Bean の型を書いておくと、Spring が自動的にそれを探して持ってきてくれる(依存性注入)」というルールがあるので、これをすると Step を呼ぶときの引数を省略できる。
「processor は引数でパラメータ(ジョブ引数)を受け取る」→「exportStep はその情報を読み込む(Spring により自動で流し込まれる)」→「exportJob は Spring により自動的に組み立てられた Step の情報を読み込む(流し込まれる)」という過程を経て、あとは Spring が引数はうまいことやってくれる・・・という仕掛けだ。なので、呼び出すときの引数を省略できる。

ま、あまり Framework を使わず、一からしこしこコードを書いてきた人間には、こういう「Framework が巧いことなってくれる」という状態がなかなかしっくり来なくて、いつまでも「どうしてこうなる?どこからこの値はきた?」ってことになるんだけど、「そういうもんだ」と納得するしかないのである(笑)

と、ここまでできたら Eclipse で実行してみる。

Eclipse で実行させるときにパラメータ(ジョブ引数)を渡したいときは、プロジェクト名の上で右ボタンメニューから「実行」→「実行の構成」を選択し、開いた窓で、まずはプロジェクト名とメインクラスを指定。

20260713_parameters01.jpg

次に、プログラムのパラメータ(引数)を設定する。これは、コマンドラインから jar を実行するときと同じように、「パラメータ名=値」という形で記述する。複数のパラメータがある場合は半角スペース区切りで入力する。

20260713_parameters02.jpg

値を設定後、「実行」ボタン押下でジョブ実行。

ログにも引数の情報が出力されている。(長いので、行の先頭は'~'に省略)

~: Started BatchDb2Csv1Application in 5.341 seconds (process running for 6.314)
~: Running default command line with: [models=2, modelName=未来電話]
~: [name=exportJob]] launched with the following parameters:
[{JobParameter{name='models', value=2, type=class java.lang.String,
identifying=true},JobParameter{name='modelName', value=未来電話,
type=class java.lang.String, identifying=true}}]
~: ★Job started: exportJob
~: Executing step: [exportStep]
~: Step: [exportStep] executed in 767ms
~: ★Job finished: exportJob with status: COMPLETED
~: [{JobParameter{name='models', value=2, type=class java.lang.String, identifying=true},JobParameter{name='modelName', value=未来電話, type=class java.lang.String, identifying=true}}] and the following status: [COMPLETED] in 785ms


出力された CSV ファイルを見ると、しっかり携帯種が「未来電話」と出ている。パラメータの設定が効いているようだ。

ID,名前,住所1,住所2,電話,記念日,内容
1,テスト太郎,広島市中区橋本町2-17,若林ビル302,082-221-7555 ,,
2,HIROSHIMATAROU,広島県廿日市市宮島町5050-11,,090-1111-2222(未来電話),19661210,誕生日
2,HIROSHIMATAROU,広島県廿日市市宮島町5050-11,,090-1111-2222(未来電話),19981003,結婚
3,中国 花子,島根県呪郡呪村1078-13,川村診療所内,0120-333-444 ,,
4,近藤まちゃ,山口県周南市銀座3丁目2-19,,080-5555-6666(未来電話),19641225,誕生日
4,近藤まちゃ,山口県周南市銀座3丁目2-19,,080-5555-6666(未来電話),20230407,死人村トレイルラン100 完走
4,近藤まちゃ,山口県周南市銀座3丁目2-19,,080-5555-6666(未来電話),20240122,死人村雪山激走フェス 2.1km地点リタイア
5,MASA SAITO,広島市中区橋本町2-17,若林ビル201,082-221-7549 ,,
6,KAORU MITARAI,山口県岩国市周東町祖生99999,,0827-85-0427 ,20011011,結婚
6,KAORU MITARAI,山口県岩国市周東町祖生99999,,0827-85-0427 ,20011210,離婚
6,KAORU MITARAI,山口県岩国市周東町祖生99999,,0827-85-0427 ,20200523,結婚
7,日本 太郎,,,009-1234-5678,,


次回は、第1パラメータの型を整数(Integer)にしているため、ここに文字列を入れられると異常終了していまう。それを回避する修正をしよう。

トラックバック(0)

このブログ記事を参照しているブログ一覧: Spring Batch 6 でパラメータを渡して起動

このブログ記事に対するトラックバックURL: https://blog.netandfield.com/mt/mt-tb.cgi/7249

コメントする

このブログ記事について

このページは、shinodaが2026年7月14日 20:15に書いたブログ記事です。

ひとつ前のブログ記事は「Oracle 起動せず・・・(パスワードの問題)」です。

次のブログ記事は「Spring Data JDBC と Oracle Driver」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

月別 アーカイブ

電気ウナギ的○○ mobile ver.

携帯版「電気ウナギ的○○」はこちら