Spring Bootでコンソールアプリケーション作るやり方を調べたところ、reference guide読む感じだとCommandLineRunner
かApplicationRunner
を使う、と書いてある。
ところで、CommandLineRunner
の実装クラスをなんとなく調べたらJobLauncherCommandLineRunner
というSpring BootでSpring Batchを動かすためのクラスがあった。このクラスのデフォルト動作はそのコンテキスト内のすべてのJob
を実行する。ただし、jobName
を指定することで特定のジョブを実行することもできる、と書いてある。この実装どうやってるのか気になったので、該当部分のソースを見てみた。
public class JobLauncherCommandLineRunner
implements CommandLineRunner, ApplicationEventPublisherAware {
@Autowired(required = false)
public void setJobs(Collection<Job> jobs) {
this.jobs = jobs;
}
@Override
public void run(String... args) throws JobExecutionException {
logger.info("Running default command line with: " + Arrays.asList(args));
launchJobFromProperties(StringUtils.splitArrayElementsIntoProperties(args, "="));
}
private void executeLocalJobs(JobParameters jobParameters)
throws JobExecutionException {
for (Job job : this.jobs) {
if (StringUtils.hasText(this.jobNames)) {
String[] jobsToRun = this.jobNames.split(",");
if (!PatternMatchUtils.simpleMatch(jobsToRun, job.getName())) {
logger.debug("Skipped job: " + job.getName());
continue;
}
}
execute(job, jobParameters);
}
}
Spring Boot起動後にCommandLineRunner
のrun
メソッドが実行される。ここの実装でジョブを起動している。また、setJbos
のインジェクションですべてのJob
のコレクションが入れられる。次にexecuteLocalJobs
メソッドで、そのすべてのJob
をいっこずつ起動している。その際、もしjobName
の指定があればマッチするジョブだけ起動して他はスキップしている。
コンソールアプリで何らかのキーで特定の機能だけ実行するのってどうやるんかな~CommandLineRunner
が複数あっても全部実行されるしな~と思ってたけど、こんな作りにすればよさそう。