[Spring Async] 1. 비동기 처리를 해보자.
04 Jun 2019
- Spring에서 제공해주는 @Async Annotation을 사용하여 비동기처리를 한다.
- 비동기로 실행하고, 결과값을 받아보자.
- 비동기로 처리 중에 발생되는 문제(Exception)를 잡아서 처리하자.
- 비동기 전송 방식이란?
@Async?
- https://spring.io/guides/gs/async-method/
기본 사용법
@Async
public void run() {
}
제약사항
- 리턴값은 void와 java.util.concurrent.Future만 사용가능하다.
- public 메소드만 사용 가능하다.
- 스스로를 호출하여 동작시킬 수 없다.(self-invocation)
설정하기
Dependency
spring-context
가 포함되어 있으면 됩니다.
Spring Configuration
- annotation :
@EnableAsync
- 기본으로 설정되어 있는
TaskExecutor
는 SimpleAsyncTaskExecutor
로 매번 Thread를 생성하여 Thread Pool이 아니다.
기본 설정 구조
@EnableAsync
@Configuration
public class AsyncConfiguration implements AsyncConfigurer {
}
공통된 Thread Pool을 사용하는 방법
AsyncConfigurer
를 implements 하여 getAsyncExecutor
method를 override 한다.
@Configuration
@EnableAsync
public class AsyncConfiguration implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setThreadNamePrefix("async-thread-");
executor.setCorePoolSize(10);
executor.setMaxPoolSize(50);
executor.setQueueCapacity(100);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy()); //추후 설명
executor.initialize();
return executor;
}
}
@Async
public void taskExecutor() {
log.info("thread run");
}
각각 다른 Thread Pool을 사용하는 방법
- 사용할 각각의 TaskExecutor를 생성한다.
@Bean("taskExecutor_1")
public Executor taskExecutor_1() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setThreadNamePrefix("each-async-thread-1-");
executor.setCorePoolSize(10);
executor.setMaxPoolSize(50);
executor.setQueueCapacity(100);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
return executor;
}
@Bean("taskExecutor_2")
public Executor taskExecutor_2() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setThreadNamePrefix("each-async-thread-2-");
executor.setCorePoolSize(10);
executor.setMaxPoolSize(50);
executor.setQueueCapacity(100);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
return executor;
}
@Async("taskExecutor_1")
public void taskExecutor1() {
log.info("thread name : {} ", Thread.currentThread().getName());
}
@Async("taskExecutor_2")
public void taskExecutor2() {
log.info("thread name : {} ", Thread.currentThread().getName());
}