I am trying async process in my code. i written code like below. But async process is not working. Thread name '' itself not showing in logs. It looks Service class is not looking bean 'asyncExecutor'. What i am missing here.
@SpringBootApplication
@EnableAsync
public class MyMainApplication {
@Bean(name = "asyncExecutor")
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(3);
executor.setMaxPoolSize(3);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("AsynchThread-");
executor.initialize();
return executor;
}
public static void main(String[] args) {
SpringApplication.run(MyMainApplication.class, args);
}
}
Service Class
public void getSampleDetails(String param1, String param2) {
log.info("Inside - getSampleDetails");
CompletableFuture<Map<String, String>> sampleMap1 = null;
CompletableFuture<Map<String, String>> sampleMap2 = null;
CompletableFuture<Map<String, String>> sampleMap3 = null;
sampleMap1 = getSampleMap1(param1, param2);
sampleMap2 = getSampleMap2(param1, param2);
sampleMap3 = getSampleMap3(param1, param2);
// Wait until they are all done
CompletableFuture.allOf(sampleMap1, sampleMap2, sampleMap3).join();
}
@Async("asyncExecutor")
public CompletableFuture<Map<String, String>> getSampleMap1(String param1, String param2) throws InterruptedException {
System.out.println("Inside Method1");
..
..
}
@Async("asyncExecutor")
public CompletableFuture<Map<String, String>> getSampleMap2(String param1, String param2) throws InterruptedException {
System.out.println("Inside Method2");
..
..
}
@Async("asyncExecutor")
public CompletableFuture<Map<String, String>> getSampleMap3(String param1, String param2) throws InterruptedException {
System.out.println("Inside Method3");
..
..
}
Thread name is not displayed and async process is not happening logs:
[ main]o.s.s.concurrent.ThreadPoolTaskExecutor Initializing ExecutorService
[ main]o.s.s.concurrent.ThreadPoolTaskExecutor Initializing ExecutorService 'asyncExecutor1'
[ main]o.s.s.c.ThreadPoolTaskScheduler Initializing ExecutorService 'taskScheduler'
[ main]o.s.b.w.embedded.tomcat.TomcatWebServer Tomcat started on port(s): 32182 (http) with context path '/myapplication'
[ main]MyMainApplication Started MyMainApplication in 46.662 seconds (JVM running for 48.024)
[exec-1]e-myapplication] Initializing Spring DispatcherServlet 'dispatcherServlet'
[exec-1]o.s.web.servlet.DispatcherServlet Initializing Servlet 'dispatcherServlet'
[exec-1]o.s.web.servlet.DispatcherServlet Completed initialization in 8 ms
[exec-1]Inside - getSampleDetails
[exec-1]Inside Method1
[exec-1]Inside Method2
[exec-1]Inside Method3
CodePudding user response:
When spring scans the bean, it will scan whether the @Async annotation is included on the method. If it is included, spring will dynamically generate a subclass (ie proxy class, proxy) for the bean, and the proxy class inherits the original bean. At this time, when the annotated method is called, it is actually called by the proxy class, and the proxy class adds asynchronous effects when it is called. However, if this annotated method is called by other methods in the same class, the method call does not go through the proxy class, but directly through the original bean, so there is no asynchronous effect, we see The phenomenon is that the @Async annotation is invalid.
You can try something like this:
- the call and task should be placed in different classes.
- Add annotation in startup class:@EnableAspectJAutoProxy(exposeProxy = true)
- In the Service Manager, use AopContext.currentProxy() to obtain the proxy class of the Service, and then call the transaction method to force through the proxy class to activate the transaction aspect.
