Spring에서 Async처리를 해보겠다..!
블로그에 정리되어 있는게 많았는데 그중에 어떤 방법을 택할까 고민을 했다.
가장 간단한 방법으로 구현하였다.
@Async
annotaion을 붙여주는 방법이다.
1. @EnableAsync로 async를 쓰겠다고 스프링에게 알린다.
2. 비동기로 수행되었으면 하는 method위에 @Async annotaion 을 붙인다.
3. method return 값은 void나 CompletableFuture<?>로 해주어야한다.
@EnableAsync은 Application을 run하는 데에다 붙여주거나,@Configuration annotaion 있는데 붙여주면 된다.
그리고 thread를 관리해주어야 하기 때문에 bean을 설정해준다.
@Bean public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(2); executor.setMaxPoolSize(2); executor.setQueueCapacity(500); executor.setThreadNamePrefix("GithubLookup-"); executor.initialize(); return executor; } |
spring boot 2.0이상이면, application.yml파일에 작성해도 auto configuration 으로 Excutor를 등록해준다.
이렇게해서,, 테스트를 해봤었는데 잘안되었다
이유는???
@Async를 활용하기 위해서는 몇가지 제약 조건이 있기 때문이다.
1.public method만 @Async가 가능하다. private는 불가능
2.self-invocation(자가 호출)해서는 안된다. -> 같은 클래스 내부의 메서드를 호출하는 것은 안된다.
나같은 경우는 2번의 경우였다.
한 service에서 계속 function call을 내부적으로 하는데
그중에 한, method만 비지니스적으로 async하게 call하고 싶었다.
그래서 찾은 방법은???
async해야 하는 method를 다른 service로 빼서 ,
기존 service에 AsyncService를 주입하고 (@Autowired)
async 해야하는 method에 @Async를 붙여준다음,
service에서 call 하면 되는 것이다 (간단간단 '-' 역시.. 알면 간단하다)
기존 service
@Service public class 기존service{ @Autowired AsyncService asyncService;
public void 해당method(){ asyncService.asyncMethod(); } } |
AsyncService
@Service public class Asyncservice{
@Async ComletableFuture<OutVO>asyncMethod(){ OutVO output = new OutVO();
return ComletableFuture.completedFuture(output); } } |
그런데 도대체 왜그럴까?? ( 블로그 글 참조)
결론부터 말하면 AOP가 적용되어 Spring context에 등록되어 있는 빈 객체의 메서드가 호출되었을 때 스프링이 끼어들 수 있고 @Async가 적용되어 있다면 스프링이 메서드를 가로채서 다른 스레드(풀)에서 실행시켜주는 메커니즘이라는 것이다. |
public이어야 가로챈 스프링의 다른 클래스에서 호출이 가능하고,
self-invocation이 불가능 했던 이유도 spring context에 등록된 빈의 메서드 호출 이어야
프록시를 적용 받을 수 있기에 내부 메서드 호출은 프록세 영향을 받지 않기 때문이다.
참고 사이트 :
https://spring.io/guides/gs/async-method/
https://jeong-pro.tistory.com/m/187
'DEVELOP > Backend' 카테고리의 다른 글
Django 시작하기 [2] 데이터베이스 만들기 (0) | 2020.03.18 |
---|---|
Django 시작하기 [1] Python , Django 설치 및 프로젝트 생성 (0) | 2020.03.18 |
테스트에서 @Transactionl 어노테이션 (0) | 2019.07.29 |
트랜잭션 속성 @Transactional (0) | 2019.07.29 |
Filter, Interceptor, AOP의 차이 이해하기~! (0) | 2019.07.26 |