스프링부트 @Async 어노테이션 비동기 백그라운드 스레드 돌리기

dropKick·2022년 2월 4일
0

공부 기록

목록 보기
52/67
  • 서버 코드에서 별도로 메소드를 호출하지 않는데 어떻게 구동하고 있지 하다가
    @Async 어노테이션을 발견하고 공부함

@Async

스프링에서 지원하는 비동기 어노테이션으로 사용하기 위해선 두 가지 제약이 존재

  • public 메소드에서만 사용
  • self-invocation 불가
    동일 클래스 내에서 async 호출 불가능

이런 제약사항이 존재하는 이유는 @Async 어노테이션이 AOP와 인터셉트 방식으로 동작하기 때문이다.
스프링 AOP에 의해 메소드 객체가 IoC 컨테이너에 등록되는 시점에서 인터셉트하여 AOP의 경우 public 메소드에서만 프록시를 만들 수 있고, self-invocation은 프록시로서의 인터셉터를 우회하고 메소드를 직접 호출하기에 적용할 수 없음

@Async 어노테이션의 동작

기본적으로 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;
    }
}

0개의 댓글