异步进程在 Spring Boot 应用程序中不起作用
Async process is not working in Springboot application
我正在我的代码中尝试异步进程。我写了如下代码。但是异步过程不起作用。线程名称“”本身未显示在日志中。它看起来 Service class 不是在寻找 bean 'asyncExecutor'。我在这里缺少什么。
@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);
}
}
服务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");
..
..
}
线程名称未显示,异步进程未发生
日志:
[ 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
spring扫描bean时,会扫描方法上是否包含@Async注解。如果包含,spring会为bean动态生成一个subclass(即proxyclass,proxy),proxyclass继承了原来的bean。这时候调用注解方法的时候,其实是调用了代理class,代理class在调用的时候添加了异步效果。但是,如果这个注解的方法被同一个class中的其他方法调用,方法调用不经过代理class,而是直接通过原始bean,所以不存在异步效果,我们看到的现象是@Async注解无效
您可以尝试这样的操作:
- 调用和任务应该放在不同的 classes 中。
- 在启动时添加注解class:@EnableAspectJAutoProxy(exposeProxy = true)
- 在ServiceManager中,使用AopContext.currentProxy()获取Service的代理class,然后调用事务方法强制通过代理class激活交易方面。
我正在我的代码中尝试异步进程。我写了如下代码。但是异步过程不起作用。线程名称“”本身未显示在日志中。它看起来 Service class 不是在寻找 bean 'asyncExecutor'。我在这里缺少什么。
@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);
}
}
服务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");
..
..
}
线程名称未显示,异步进程未发生 日志:
[ 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
spring扫描bean时,会扫描方法上是否包含@Async注解。如果包含,spring会为bean动态生成一个subclass(即proxyclass,proxy),proxyclass继承了原来的bean。这时候调用注解方法的时候,其实是调用了代理class,代理class在调用的时候添加了异步效果。但是,如果这个注解的方法被同一个class中的其他方法调用,方法调用不经过代理class,而是直接通过原始bean,所以不存在异步效果,我们看到的现象是@Async注解无效
您可以尝试这样的操作:
- 调用和任务应该放在不同的 classes 中。
- 在启动时添加注解class:@EnableAspectJAutoProxy(exposeProxy = true)
- 在ServiceManager中,使用AopContext.currentProxy()获取Service的代理class,然后调用事务方法强制通过代理class激活交易方面。