CommandLineRunner 인터페이스는 서버 시작 시점에 실행된다.
@Component 어노테이션을 통해 Bean 으로 등록되고 구동되는 시점에 run 메소드가 실행된다.
새로운 Class 로 만들어 사용하거나, CommanLineRunner 를 return 하는 메서드를 @Bean 어노테이션으로 정의하여 사용할 수 있다.
// CommandLineRunnerApp.java
@Component
public class CommandLineRunnerApp implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("Arguments: " + Arrays.toString(args));
}
}
@Bean
public CommandLineRunner schedulingRunner() {
return args -> {
System.out.println("Arguments: " + Arrays.toString(args));
};
}
CommanLineRunner 의 run 메서드에 Runnable 을 interface 한 객체를 실행(run) 할 수도 있겠지만, 이런 경우 여러개의 thread 생성이 불가능하고 하나의 runnable 이 종료되어야 다음 runnable 객체를 수행 할 수 있다.
sout 후 5초간 Sleep 하고 sout 하는 runnable MyThread 가 있을 때
그냥 runnable.run()을 실행하면 멀티스레드가 적용되지 않는 모습을 볼 수 있다.
public class MyThread implements Runnable{
int id;
public MyThread(int id){this.id = id;}
@Override
public void run(){
try {
System.out.println("Runnable START id: "+id);
Thread.sleep(5000);
System.out.println("Runnable END id: "+id);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Bean
public CommandLineRunner schedulingRunner() {
return args -> {
for (int i = 0; i < 2; i++) {
new MyThread(i).run();
}
};
}
결과
Runnable START id: 0
Runnable END id: 0
Runnable START id: 1
Runnable END id: 1
멀티스레드를 적용 시키려면 TaskExecutor를 사용하여야한다.
TaskExecutor bean 을 생성하고 이를 commanLineRunner 에서 실행 시키면 된다.
@Bean(name="executor")
public TaskExecutor taskExecutor() {
return new SimpleAsyncTaskExecutor();
}
@Bean
public CommandLineRunner schedulingRunner(TaskExecutor executor) {
return args -> {
for (int i = 0; i < 2; i++) {
executor.execute(new MyThread(i));
}
};
}
결과
Runnable START id: 1
Runnable START id: 0
Runnable END id: 0
Runnable END id: 1