Spring BootでCommandLineRunnerを使ってはいけない

# 概要
Spring Applicationが起動した後の処理を書く方法として、CommandLineRunnerを使うか、ApplicationRunnerを使うという方法があります。どっちを使えばいいの？と迷うところですが、ApplicationRunnerを推奨します。
[Spring Boot Features / 1.10. Using the ApplicationRunner or CommandLineRunner](https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-command-line-runner)（参考リンク1）

# ApplicationRunnerを使う理由（CommandLineRunnerを使ってはいけない理由）
引数の扱いに違いがあります。逆に言うと、引数を使わないアプリケーションであれば、どちらを使っても問題ありません。
例えば、アプリケーションの引数として「arg1 arg2」が設定されている状態で、Webサーバのポートを変えるために、「--server.port=8081」という引数を追加したときに、違いが表れてきます。

# 実例
どちらも引数を標準出力に表示するプログラムです。

## CommandLineRunner
```java:TestCommandLineRunner.java
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
```java:TestApplicationRunner
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](https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config)（参考リンク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](https://stackoverflow.com/questions/48011632/where-is-spring-output-ansi-enabled-configured)（参考リンク3）
に記載の通り、STSのRun Configurationで「ANSI console output」のチェックが入っていると、自動的に設定される引数のようです。ApplicationRunnerを使っていれば、正しく引数を処理できますね。

# 動作環境
OpenJDK11.0.2
Spring Boot 2.3.2

# 参考
1. [Spring Boot Features / 1.10. Using the ApplicationRunner or CommandLineRunner](https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-command-line-runner)
2. [Spring Boot Features - 2. Externalized Configuration](https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config)
3. [Where is --spring.output.ansi.enabled configured? - Stack Overflow](https://stackoverflow.com/questions/48011632/where-is-spring-output-ansi-enabled-configured)