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();
    }

 

참고 블로그 : 스프링부트는 사랑입니다

복사했습니다!