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.
- Write a method annotated with @Async annotation.
Enable scheduling annotations
To enable support for @Async annotation add @EnableAsync to one of your @Configuration classes. Also define a TaskExecutor.
In case of XML configuration you can configure it as following using the task name space.
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;
}
}
<?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, JDK 8’s java.util.concurrent.CompletableFuture.
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)
To run the above example you can use the following code.
@Async
void doSomething(String s) {
// this will be executed asynchronously
}
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 Asynchronous Method Execution Support Using @Async Annotation. If you have any doubt or any suggestions to make please drop a comment. Thanks!
Related Topics
You may also like -