@Async
비동기 프로그램을 작성하기 위해서 복잡한 계산, I/O 작업 등 병렬로 처리하면서 시스템의 응답 시간을 개선하기 위해 혹은 리소스를 효율적으로 사용하기 위해 사용된다.
- 스프링에서 간단하게 작성할 수 있도록 지원하는 애너테이션이다.
Exception Handling
@Async 메서드에서 발생하는 예외는 별도의 스레드에서 실행되기 때문에 호출자에게 전파가 되지 않는다.
- 예외를 처리하기 위해서는 AsyncUncaughtExceptionHandler를 사용하여 예외를 처리해야 합니다.
AsyncConfigurer를 구현하는 클래스
AsyncConfigurerSupport를 사용한 확장은 deprecate 되었습니다. (참조)
AsyncUncaughtExceptionHandler를 구현하는 클래스
AsyncConfigurer에 커스텀으로 예외 처리한 코드를 getAsyncUncaughtExceptionHandler()를 오버라이딩하여 정의해주면 예외 핸들러를 사용할 수 있습니다.
- AsyncUncaughtExceptionHandler는 함수형 인터페이스라서 간단하게 람다로 사용할 수 있습니다.
AsyncConfigurer를 구현하는 클래스에서 람다 사용하기
- 람다 블럭에서 메서드 길이가 길어지면 가독성이 많이 안좋아지기 때문에 분리하는 것도 좋아보인다.
이벤트 비동기로 처리하기
Spring은 다수의 ApplicationListener 객체를 관리하고 객체에 이벤트를 전달하기 위한 인터페이스 ApplicationEventMulticaster의 이름을 통해서 빈을 찾고 없으면 기본적으로 만들어둔 SimpleApplicationEventMulticaster를 생성해 빈으로 등록한다.
추가적으로 application단에 @EnableAsync를 선언하고, 비동기로 콜할 method에 @Async를 선언할 때 @Async의 기본설정인 SimpleAsyncTaskExecutor를 사용하게 된다.
- SimpleAsyncTaskExecutor는 비동기 작업마다 새로운 스레드를 생성하는 스레드풀이기 때문에 리소스 낭비, 성능 저하, 스케일링 문제 등이 발생할 수 있어서 SimpleAsyncTaskExecutor 보다는 ThreadPoolTaskExecutor 같은 제한된 리소스를 사용하는 스레드풀을 사용하는 것이 좋다.
ThreadPoolTaskExecutor는 Java의 ThreadPoolExecutor를 Wrapping 한 것으로, 스프링에서 제공하는 TaskExecutor 인터페이스의 구현체다.
- Excutor를 저의하기 위해서는 Bean으로 등록하거나 AsyncConfigurer 인터페이스의 getAsyncExecutor()를 재정의하면 된다.
따라서 비동기 메서드와 이벤트를 비동기로 처리하기 위해서 다음과 같이 설정을 구현할 수 있습니다.
사용할 때는 @Async 애너테이션 value 값에 빈으로 등록한 threadPoolTaskExecutor 이름을 넣어주면 된다.
@Aysnc 애너테이션을 메서드에 붙일 때 알고 있어야 하는 것들
Async를 적용하는 메서드의 접근제어자는 private이면 안된다.
- 비동기 메서드는 Spring AOP를 기반으로 동작하기 때문에 프록시 객체를 통해 호출되기 때문이다.
- 따라서 @Aysnc 메서드가 붙여지지 않은 메서드 호출을 통해서 메서드를 호출하는 경우 비동기로 처리가 되지 않는다.
- 물론 @Aysnc 메서드가 붙여진 메서드를 바로 호출하면 상관없다.
트랜잭션 전파를 공부하면서 @Transactional 문제를 해결했던 것 처럼 다른 클래스에서 호출하거나 같은 클래스에서 호출한다면 self reference를 사용하면 된다.
로그를 확인해보면 다른 쓰레드에서 동작하는것을 확인할 수 있었다.
📚 reference
'개발' 카테고리의 다른 글
java에서 이미지 작업 및 최적화하기 (0) | 2024.06.11 |
---|---|
도메인 주도 설계의 사실과 오해 (0) | 2024.04.29 |
Getter 없이 Test해보기 (1) | 2023.11.24 |
EnumMap 적용하기! (1) | 2023.11.08 |
매직넘버, 리터럴 어디까지 상수 처리해야 돼? (4) | 2023.11.06 |