MTP 메일 전송중 N명에게 전송해야하는 로직이 있었다.
동기로 처리하기엔 100명에게 메일을 보낼 경우
한명 당 1초가 걸린다면 1분40초가 걸리는 것이다.
그래서 비동기처리를 하도록 하였다.
Async 기능 켜기
- 자바 설정Java configuration으로 비동기 처리enabling asynchronous processing를 쓰려면 간단히 설정 클래스에 @EnableAsync를 추가해주기만 하면 된다 또는 SpringApplication에 추가해주어도 좋다.
@Configuration
@EnableAsync
public class SpringAsyncConfig { ... }
@EnableCaching
@EnableAsync
@EnableScheduling
@SpringBootApplication(exclude = {GsonAutoConfiguration.class})
public class Application {...}
@Async 어노테이션 제약사항
- public 메소드에만 적용해야한다
- 같은 클래스안에서 async 메소드를 호출 – 은 작동하지않음
- 리턴타입이 있는 메소드 - Future 객체에 실제 리턴값을 넣음으로서 @Async 는 리턴타입이 있는 메소드에 적용할 수 있다.
@Async
public Future<String> asyncMethodWithReturnType() {
System.out.println("Execute method asynchronously - " + Thread.currentThread().getName());
try {
Thread.sleep(5000);
return new AsyncResult<String>("hello world !!!!");
} catch (InterruptedException e) {
//
}
return null;
}
config 실행자 설정하기
메소드 레벨로 설정
@Configuration
@EnableAsync
public class SpringAsyncConfig {
@Bean(name = "threadPoolTaskExecutor")
public Executor threadPoolTaskExecutor() {
return new ThreadPoolTaskExecutor();
}
@Async("threadPoolTaskExecutor")
public void asyncMethodWithConfiguredExecutor() {
System.out.println("Execute method with configured executor - " + Thread.currentThread().getName());
}
}
어플리케이션 레벨로 설정
@Configuration
@EnableAsync
public class SpringAsyncConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
return new ThreadPoolTaskExecutor();
}
}
예외 처리하기
- 메소드의 리턴타입이 Future일 경우 예외처리는 쉽다 - Future.get() 메소드가 예외를 발생한다. 하지만 리턴타입이 void일 때, 예외는 호출 스레드에 전달되지 않을 것이다. 따라서 우리는 예외 처리를 위한 추가 설정이 필요하다.
- 섹션에서 우리는 설정 클래스에 의해 구현된 AsyncConfigurer 인터페이스를 보았다. 그 일부로서 우리의 커스텀 비동기 예외처리자를 리턴하는 getAsyncUncaughtExceptionHandler() 메소드 또한 오버라이드해주어야한다
public class CustomAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
System.out.println("Exception message - " + throwable.getMessage());
System.out.println("Method name - " + method.getName());
for (Object param : obj) {
System.out.println("Parameter value - " + param);
}
}
}
@Configuration
@EnableAsync
public class SpringAsyncConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
return new ThreadPoolTaskExecutor();
}
@Override // 추가
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new CustomAsyncExceptionHandler();
}
'몰아 넣기' 카테고리의 다른 글
[Spring] Swagger3 사용해보기 (0) | 2023.02.05 |
---|---|
[자바] 박싱과 언박싱에 대해서 (0) | 2023.02.05 |
[java/spring] Stream의 안좋은 예시 :1 (0) | 2022.12.24 |
[Spring]@Valid, @Validated 에 대해서 정리[3] - DTO구조를 이용한 @Valid (0) | 2022.11.27 |
[자바/자료구조] Array(배열)과 LinkedList(연결 리스트) 그리고 ArrayList에 대한 정리[2] - ArrayList 사용법과 예제 (0) | 2022.09.04 |