gpt4 book ai didi

java - Controller 中的 Spring Boot @Async 方法正在同步执行

转载 作者:IT老高 更新时间:2023-10-28 20:37:20 29 4
gpt4 key购买 nike

我的 [基本] Spring Boot 应用程序接受来自浏览器的请求,通过 jQuery.get() 发送并且应该立即收到响应 - 例如“您的请求已被排队”。为此,我编写了一个 Controller :

@Controller
public class DoSomeWorkController {

@Autowired
private final DoWorkService workService;

@RequestMapping("/doSomeWork")
@ResponseBody
public String doSomeWork() {

workService.doWork(); // time consuming operation
return "Your request has been queued.";
}
}

DoWorkServiceImpl 类实现了一个DoWorkService 接口(interface),非常简单。它有一个单一的方法来执行一项耗时的任务。我不需要从此服务调用返回的任何内容,因为将在工作结束时发送一封电子邮件,无论是失败还是成功场景。所以它实际上看起来像:

@Service
public class DoWorkServiceImpl implements DoWorkService {

@Async("workExecutor")
@Override
public void doWork() {

try {
Thread.sleep(10 * 1000);
System.out.println("completed work, sent email");
}
catch (InterruptedException ie) {
System.err.println(ie.getMessage());
}
}
}

我认为这会起作用,但是浏览器的 Ajax 请求在返回响应之前等待了 10 秒。因此, Controller 映射方法似乎是同步调用了带有 @Async 注释的内部方法。在传统的 Spring 应用程序中,我通常将其添加到 XML 配置中:

<task:annotation-driven />
<task:executor id="workExecutor" pool-size="1" queue-capacity="0" rejection-policy="DISCARD" />

所以我认为在主应用程序类中编写等效的代码会有所帮助:

@SpringBootApplication
@EnableAsync
public class Application {

@Value("${pool.size:1}")
private int poolSize;;

@Value("${queue.capacity:0}")
private int queueCapacity;

@Bean(name="workExecutor")
public TaskExecutor taskExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setMaxPoolSize(poolSize);
taskExecutor.setQueueCapacity(queueCapacity);
taskExecutor.afterPropertiesSet();
return taskExecutor;
}

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

这并没有改变行为。 Ajax 响应在发送请求 10 秒后仍然到达。我错过了什么?

Spring Boot 应用程序可以是 downloaded here .安装 Maven 后,可以使用简单的命令运行项目:

mvn clean spring-boot:run

注意由于下面@Dave Syer 提供的答案,该问题得到了解决,他指出我的应用程序中缺少 @EnableAsync,即使我有上面代码片段中的那一行。

最佳答案

您正在从同一类中的另一个方法调用 @Async 方法。除非您为 @EnableAsync 启用 AspectJ 代理模式(当然并提供一个编织器),否则它将无法工作(谷歌“代理自调用”)。最简单的解决方法是将 @Async 方法放在另一个 @Bean 中。

关于java - Controller 中的 Spring Boot @Async 方法正在同步执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29284008/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com