【问题标题】:Async process is not working in Springboot application [duplicate]异步进程在 Springboot 应用程序中不起作用 [重复]
【发布时间】:2022-01-21 00:50:53
【问题描述】:

我正在我的代码中尝试异步进程。我写了如下代码。但是异步进程不起作用。线程名称“”本身未显示在日志中。看起来服务类不是在寻找 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);
    }

}

服务类

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 

【问题讨论】:

  • 你是从同一个类的另一个方法中调用@Async-annotated 方法吗?如果是这样,请参阅stackoverflow.com/questions/29284008/…
  • 是的。我正在调用 3 个必须异步执行的方法,结果应该在调用方法中返回。我没有从上面的链接中理解这个答案>

标签: java multithreading spring-boot asynchronous


【解决方案1】:

spring在扫描bean时,会扫描方法上是否包含@Async注解。如果包含,spring会为这个bean动态生成一个子类(即代理类,proxy),代理类继承原bean。这时候,被注解的方法被调用的时候,其实是被代理类调用的,代理类在调用的时候加入了异步效果。但是如果这个注解的方法被同一个类中的其他方法调用,方法调用并没有经过代理类,而是直接通过原始bean,所以没有异步效果,我们看到的现象是@Async注释无效。

你可以试试这样的:

  1. 调用和任务应该放在不同的类中。
  2. 在启动类中添加注解:@EnableAspectJAutoProxy(exposeProxy = true)
  3. 在ServiceManager中,使用AopContext.currentProxy()获取Service的代理类,然后调用事务方法强制通过代理类激活事务切面。

【讨论】:

  • 很高兴为您提供帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-28
  • 2019-08-19
  • 1970-01-01
  • 2018-12-07
  • 2016-08-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多