Getting Started with Spring Boot - Advanced (2) - Asynchronous Call (@Async)

Asynchronous processing
  • Java's asynchronous processing of Thread/Runnable, Callable/Future
  • Asynchronous processing of Servlet 2.5 Tomcat's CometProcessor, Jetty's Continuations
  • Asynchronous processing of Servlet 3.0 asyncSupported, AsyncContext
  • Asynchronous processing of Spring MVC @Async, AsyncTaskExecutor
  • Spring MVC的SSE ResponseBodyEmitter、SseEmitter、StreamingResponseBody


Spring Boot itself has not changed much for asynchronous calls, and it is basically Spring MVC's @Async.

(1) Turn on Spring's asynchronous support
@Configuration
@EnableAsync
public class SpringAsyncConfig {

}


Asynchronous processing is also automatically enabled when @EnableWebMvc is enabled, but @EnableWebMvc cannot be used in Spring Boot projects. It disables part of Spring Boot's AutoConfigure functionality.
There are instructions in the official documentation:
http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-spring-mvc-auto-configuration

@EnableWebMvc
@ComponentScan("com.example.component")
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
        configure.setTaskExecutor (mvcAsyncExecutor ());
    }

    @Bean
    public AsyncTaskExecutor mvcAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setMaxPoolSize(10);
        return executor;
    }
}



(2) Define a method that needs to perform asynchronous processing

1) No return value
@Async
public void asyncMethodWithVoidReturnType() {
    System.out.println("Execute method asynchronously. "
      + Thread.currentThread().getName());
}

2) with return value
@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;
}


(3) Definition of asynchronous thread pool

1) A thread pool

@Configuration
@EnableAsync
public class SpringAsyncConfig {
    @Bean
    public AsyncTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setMaxPoolSize(10);
        return executor;
    }
}


2) Multiple thread pools

@Configuration
@EnableAsync
public class SpringAsyncConfig {
     
    @Bean(name = "threadPoolTaskExecutor1")
    public Executor threadPoolTaskExecutor() {
        return new ThreadPoolTaskExecutor();
    }
     
    @Bean(name = "threadPoolTaskExecutor2")
    public Executor threadPoolTaskExecutor() {
        return new ThreadPoolTaskExecutor();
    }

}


@Async("threadPoolTaskExecutor1")
public void asyncMethodWithConfiguredExecutor() {
    System.out.println("Execute method with configured executor - "
      + Thread.currentThread().getName());
}


(4) Handling of asynchronous exceptions

public interface AsyncConfigurer {
    Executor getAsyncExecutor();
    AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler();
}


AsyncConfigurerSupport is an implementation of the AsyncConfigurer interface but does nothing in it.
@Configuration
@EnableAsync
class SpringAsyncConfigurer extends AsyncConfigurerSupport {

    @Bean
    public ThreadPoolTaskExecutor asyncExecutor() {
        ThreadPoolTaskExecutor threadPool = new ThreadPoolTaskExecutor();
        threadPool.setCorePoolSize(3);
        threadPool.setMaxPoolSize(3);
        threadPool.setWaitForTasksToCompleteOnShutdown(true);
        threadPool.setAwaitTerminationSeconds(60 * 15);
        return threadPool;
    }

    @Override
    public Executor getAsyncExecutor() {
        return asyncExecutor;
    }
}


You can implement the AsyncConfigurer interface yourself to handle exceptions.
@Configuration
@EnableAsync
public class SpringAsyncConfigurer implements AsyncConfigurer {
     
    @Override
    public Executor getAsyncExecutor() {
        return new ThreadPoolTaskExecutor();
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new CustomAsyncExceptionHandler();
    }

}

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


Reference:
http://qiita.com/kazuki43zoo/items/8be79f98621f90865b78
http://qiita.com/kazuki43zoo/items/ce88dea403c596249e8a
http://qiita.com/kazuki43zoo/items/53b79fe91c41cc5c2e59

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326604730&siteId=291194637