In this post we’ll see Spring support for asynchronous method execution using @Async annotation and how to enable support for it using @EnableAsync if you are using Java configuration.
Spring @Async annotation
When a method is annotated with @Async annotation the invocation of that method will occur asynchronously. Which means the caller will return immediately upon invocation and the actual execution of the method will occur in a task that has been submitted to a Spring TaskExecutor.
Spring asynchronous method invocation example
For asynchronous method execution using @Async annotation in Spring framework following tasks are required.
- Enable scheduling annotations
- Define a TaskExecutor that will execute the method as a submitted task. In the example ThreadPoolTaskExecutor implementation of the TaskExecutor is used.
- Write a method annotated with @Async annotation.
Enable scheduling annotations using @EnableAsync annotation
To enable support for @Async annotation add @EnableAsync to one of your @Configuration classes. Also define a TaskExecutor.
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.core.task.TaskExecutor; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @Configuration @EnableAsync @ComponentScan(basePackages = "org.netjs.service") public class AppConfig { @Bean public TaskExecutor threadPoolTaskExecutor() { ThreadPoolTaskExecutor ex = new ThreadPoolTaskExecutor(); ex.setCorePoolSize(4); ex.setMaxPoolSize(6); ex.setQueueCapacity(10); ex.initialize(); return ex; } }In case of XML configuration you can configure it as following using the task name space.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/task http://www.springframework.org/task/spring-task.xsd"> <context:component-scan base-package="org.netjs.service" /> <task:annotation-driven executor="taskExecutor" /> <task:executor id="taskExecutor" pool-size="5" queue-capacity="10"/> </beans>
Service with @Async annotated method
@Service public class EmployeeService { @Async public CompletableFuture<Integer> getEmployeeCount(){ int count = 0; Object obj = em.createQuery("SELECT COUNT(emp) FROM Employee emp").getSingleResult(); if(obj instanceof Integer){ count=(Integer)obj; }else if(obj instanceof Long){ count=((Long)obj).intValue(); } return CompletableFuture.completedFuture(count); } }
Here we have a method that returns a value which has to be invoked asynchronously. Note that such methods are required to have a Future typed return value. @Async methods may not only declare a regular java.util.concurrent.Future return type but also Spring’s org.springframework.util.concurrent.ListenableFuture or, as of Spring 4.2, CompletableFuture in Java too.
You can also apply the @Async annotation to a void-returning method.
@Async void doSomething() { // this will be executed asynchronously }
Or to a method with argument(s)
@Async void doSomething(String s) { // this will be executed asynchronously }To run the above example you can use the following code.
public class App { public static void main( String[] args ){ AbstractApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); EmployeeService employeeService = context.getBean("employeeService", EmployeeService.class); CompletableFuture<Integer> cf = employeeService.getEmployeeCount(); try { System.out.println("Count--" + cf.get()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } context.registerShutdownHook(); } }
If you are using XML Configuration not Java config then you may need to use ClassPathXmlApplicationContext in place of AbstractApplicationContext.
That's all for this topic Spring @Async @EnableAsync Annotations - Asynchronous Method Support. If you have any doubt or any suggestions to make please drop a comment. Thanks!
>>>Return to Spring Tutorial Page
Related Topics
You may also like-
No comments:
Post a Comment