概要
Spring Applicationが起動した後の処理を書く方法として、CommandLineRunnerを使うか、ApplicationRunnerを使うという方法があります。どっちを使えばいいの?と迷うところですが、ApplicationRunnerを推奨します。
Spring Boot Features / 1.10. Using the ApplicationRunner or CommandLineRunner(参考リンク1)
ApplicationRunnerを使う理由(CommandLineRunnerを使ってはいけない理由)
引数の扱いに違いがあります。逆に言うと、引数を使わないアプリケーションであれば、どちらを使っても問題ありません。
例えば、アプリケーションの引数として「arg1 arg2」が設定されている状態で、Webサーバのポートを変えるために、「--server.port=8081」という引数を追加したときに、違いが表れてきます。
実例
どちらも引数を標準出力に表示するプログラムです。
CommandLineRunner
package com.example.demo;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@Component
public class TestCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println(" - CommandLineRunner - ");
for(int i=0; i<args.length; i++) {
System.out.printf("%s:%s\n", i, args[i]);
}
}
}
ApplicationRunner
package com.example.demo;
import java.util.List;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
@Component
public class TestApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println(" - ApplicationRunner - ");
List<String> argsList = args.getNonOptionArgs();
for(int i=0; i<argsList.size(); i++) {
System.out.printf("%s:%s\n", i, argsList.get(i));
}
}
}
args.getNonOptionArgsで、先頭に「--」の付いていない引数のみを取得しています。
実行結果
上記のアプリケーションを、引数「arg1 arg2」で実行した場合の結果は下記の通りです。
- ApplicationRunner -
0:arg1
1:arg2
- CommandLineRunner -
0:arg1
1:arg2
違いはありません。
実例(引数を追加した場合)
たとえば、Webサーバのポートを変えるために、「--server.port=8081」という引数を追加します。
Spring Boot Features - 2. Externalized Configuration(参考リンク2)
実行結果
上記のアプリケーションを、引数「arg1 arg2 --server.port=8081」で実行した場合の結果は下記の通りです。
- ApplicationRunner -
0:arg1
1:arg2
- CommandLineRunner -
0:arg1
1:arg2
2:--server.port=8081
ApplicationRunnerの方は結果が変わりませんが、CommandLineRunnerの方は、追加した引数が取れています。Spring Bootの動作を変えるための引数で、アプリケーションでは不要(のはず)なので、「--server.port=8081」の引数は取れない方がよいのではと思います。もちろん、取ることもできます。
System.out.println(args.getOptionValues("server.port"));
=> [8081]
STSで実行すると、「--spring.output.ansi.enabled=always」がargs[0]に入る件
Where is --spring.output.ansi.enabled configured? - Stack Overflow(参考リンク3)
に記載の通り、STSのRun Configurationで「ANSI console output」のチェックが入っていると、自動的に設定される引数のようです。ApplicationRunnerを使っていれば、正しく引数を処理できますね。
動作環境
OpenJDK11.0.2
Spring Boot 2.3.2