스프링에서 지원하는 비동기 어노테이션으로 사용하기 위해선 두 가지 제약이 존재
이런 제약사항이 존재하는 이유는 @Async 어노테이션이 AOP와 인터셉트 방식으로 동작하기 때문이다.
스프링 AOP에 의해 메소드 객체가 IoC 컨테이너에 등록되는 시점에서 인터셉트하여 AOP의 경우 public 메소드에서만 프록시를 만들 수 있고, self-invocation은 프록시로서의 인터셉터를 우회하고 메소드를 직접 호출하기에 적용할 수 없음
기본적으로 ThreadPool Executor를 이용한 Thread Pool을 활용
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class asyncThreadTaskExecutor {
static ExecutorService executorService = Executors.newFixedThreadPool();
public void asyncMethod(final String message) throws Exception {
executorService.submit(new Runnable() {
@Override
public void run() {
}
});
}
}
기존의 자바 concurrent 패키지 방식은 비동기 메소드의 동작을 override 해주어야 했음
하지만 @Async 어노테이션의 경우 기존의 Application Context 클래스에 @EnableAsync를 추가
@EnableAsync
@SpringBootApplication
public class SpringBootApplication {
}
비동기로 동작하길 원하는 메소드에 @Async 어노테이션을 붙이는 것과
public class Async {
@Async
public void asyncMethod() {
}
}
@Async가 가지고 있는 AsyncConfigurerSupoort를 통해 Customize TaskExecutor를 구현하는 것으로 완성된다
@Configuration
@EnableAsync // 비동기 활성화
public class AsnycConfig extend AsyncConfigurationSupport {
@Bean
public Executor getAsyncExecutor() {
final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(); // 기본 스레드 풀
executor.setMaxPoolSize(); // 최대 스레드 풀
executor.setQueueCapacity(); // 스레드 풀의 대기 큐 크기
executor.setThreadNamePrefix(""); // 스레드 접두사
executor.initialize();
return executor;
}
}