Spring Boot @Async method in controller is executing synchronously Spring Boot @Async method in controller is executing synchronously ajax ajax

Spring Boot @Async method in controller is executing synchronously


You are calling the @Async method from another method in the same class. Unless you enable AspectJ proxy mode for the @EnableAsync (and provide a weaver of course) that won't work (google "proxy self-invocation"). The easiest fix is to put the @Async method in another @Bean.


For all those who are still looking for all the steps in @Asnyc explained in a simple way, here is the answer:

Here is a simple example with @Async. Follow these steps to get @Async to work in your Spring Boot application:

Step 1: Add @EnableAsync annotation and Add TaskExecutor Bean to Application Class.

Example:

@SpringBootApplication@EnableAsyncpublic class AsynchronousSpringBootApplication {    private static final Logger logger = LoggerFactory.getLogger(AsynchronousSpringBootApplication.class);    @Bean(name="processExecutor")    public TaskExecutor workExecutor() {        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();        threadPoolTaskExecutor.setThreadNamePrefix("Async-");        threadPoolTaskExecutor.setCorePoolSize(3);        threadPoolTaskExecutor.setMaxPoolSize(3);        threadPoolTaskExecutor.setQueueCapacity(600);        threadPoolTaskExecutor.afterPropertiesSet();        logger.info("ThreadPoolTaskExecutor set");        return threadPoolTaskExecutor;    }    public static void main(String[] args) throws Exception {  SpringApplication.run(AsynchronousSpringBootApplication.class,args); }}

Step 2: Add Method which executes an Asynchronous Process

@Servicepublic class ProcessServiceImpl implements ProcessService {    private static final Logger logger = LoggerFactory.getLogger(ProcessServiceImpl.class);    @Async("processExecutor")    @Override    public void process() {        logger.info("Received request to process in ProcessServiceImpl.process()");        try {            Thread.sleep(15 * 1000);            logger.info("Processing complete");        }        catch (InterruptedException ie) {            logger.error("Error in ProcessServiceImpl.process(): {}", ie.getMessage());        }    }}

Step 3: Add an API in the Controller to execute the asynchronous processing

@Autowiredprivate ProcessService processService;@RequestMapping(value = "ping/async", method = RequestMethod.GET)    public ResponseEntity<Map<String, String>> async() {        processService.process();        Map<String, String> response = new HashMap<>();        response.put("message", "Request is under process");        return new ResponseEntity<>(response, HttpStatus.OK);    }

I have also written a blog and a working application on GitHub with these steps. Please check: http://softwaredevelopercentral.blogspot.com/2017/07/asynchronous-processing-async-in-spring.html


I had a similar issue and I had the annotations @Async and @EnableAsync in the correct beans and still the method was executing synchronously. After I checked the logs there was a warning saying that I had more than one bean of type ThreadPoolTaskExecutor and none of them called taskExecutor So...

@Bean(name="taskExecutor")public ThreadPoolTaskExecutor defaultTaskExecutor() {     ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();     //Thread pool configuration     //...     return pool;}

See http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/concurrent/ThreadPoolTaskExecutor.html for the configuration available for the thread pool.