Preface:
Catch exceptions when using @ Async annotation with Spring project. When multiple threads make asynchronous calls to tasks, the solution is very simple. You need to inject your own Exception handler to catch the Exception when executing the @ Async method.
1. AsyncConfigurer: AsyncConfigurer is an interface provided by Spring. It provides two methods: one is to override TaskExecutor (Threadpool), the other is exception handler, in which you can inject exception handler to catch uncaught exception. You can create your own class and implement it directly. But I will not, as an alternative, use the Spring AsyncConfigurerSupport class, annotated by @ Configuration and @ EnableAsync, with a default implementation.
import java.lang.reflect.Method; import java.util.concurrent.Executor; import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; import org.springframework.context.annotation.Configuration; import org.springframework.core.task.SimpleAsyncTaskExecutor; import org.springframework.lang.Nullable; import org.springframework.scheduling.annotation.AsyncConfigurerSupport; import org.springframework.scheduling.annotation.EnableAsync; /** *Custom ExceptionHandler configuration */ @Configuration @EnableAsync public class CustomConfiguration extends AsyncConfigurerSupport { @Override public Executor getAsyncExecutor() { return new SimpleAsyncTaskExecutor(); } @Override @Nullable public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { //lambda expressions as exception handlers return (throwable, method, obj)->{ System.out.println("Exception Caught in Thread - " + Thread.currentThread().getName()); System.out.println("Exception message - " + throwable.getMessage()); System.out.println("Method name - " + method.getName()); for (Object param : obj) { System.out.println("Parameter value - " + param); } }; } }
Create an asynchronous method that throws an exception.
import java.util.Map; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; /*Define exception capture triggers*/ @Component public class AsyncMailTrigger { @Async public void sendMailwithException() throws Exception{ throw new Exception("SMTP Server not found :: orginated from Thread :: " + Thread.currentThread().getName()); } }
3. Create a call Caller.
import java.util.HashMap; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; @Component public class AsyncCaller { @Autowired AsyncMailTrigger asyncMailTriggerObject; public void rightWayToCall() throws Exception { System.out.println("Calling From rightWayToCall Thread " + Thread.currentThread().getName()); asyncMailTriggerObject.senMailwithException(); } }
4. Create operation main class:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.scheduling.annotation.EnableAsync; import com.example.ask2shamik.springAsync.demo.AsyncCaller; @SpringBootApplication public class DemoApplication { @Autowired AsyncCaller caller; public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @Bean public CommandLineRunner commandLineRunner(ApplicationContext ctx) { return args -> { caller.rightWayToCall(); }; } } //Output results: //Calling From rightWayToCall Thread main //Exception Caught in Thread - SimpleAsyncTaskExecutor-1 //Exception message - SMTP Server not found:: originated from Thread:: //SimpleAsyncTaskExecutor-1 //Method name - senMailwithException
Spring-@Async use reference: https://blog.csdn.net/u011663149/article/details/88561868