• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

解决SpringBoot中使用@Async注解失效的问题

springboot 搞代码 4年前 (2022-01-09) 17次浏览 已收录 0个评论

本文来源gao.dai.ma.com搞@代*码(网$错误示例,同一个类中使用异步方法:

package com.xqnode.learning.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/test")
public class TestController {

 @GetMapping("/async")
 public Map<Object, Object> test() throws InterruptedException, JsonProcessingException {
  System.out.println("接收到请求。。。");
  task();
  Map<Object, Object> map = new HashMap<>();
  System.out.println("请求结束。。。");
  map.put("msg", "操作成功");
  map.put("code", "0");
  return map;
 }

 @Async
 void task() throws InterruptedException {
  TimeUnit.SECONDS.sleep(5);
  System.out.println("线程任务执行结束。。。");
 }
}

来分析下错误的原因:

当我使用postman调用该接口的时候发现,我预想中的立即返回并没有发生。后来查询资料发现,在controller调用本类中的异步方法,不会生效

正确示例:

package com.xqnode.learning.controller;

import com.xqnode.learning.service.AsyncService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/test")
public class TestController {

 private static final Logger LOG = LoggerFactory.getLogger(TestController.class);

 @Autowired
 private AsyncService asyncService;

 @GetMapping("/async")
 public Map<Object, Object> test() throws InterruptedException {
  LOG.info("接收到请求。。。");
  asyncService.task();
  Map<Object, Object> map = new HashMap<>();
  LOG.info("请求结束。。。");
  map.put("msg", "操作成功");
  map.put("code", "0");
  return map;
 }
}

将异步调用放到service中:

package com.xqnode.learning.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class AsyncService {

 private static final Logger LOG = LoggerFactory.getLogger(AsyncService.class);


 @Async("asyncExecutor")
 public void task() throws InterruptedException {

  TimeUnit.SECONDS.sleep(5);
  LOG.info("线程任务执行结束。。。");
 }
}

这时候再重启项目请求该接口,就会发现接口可以立即返回值。而task任务是异步执行的,5秒之后才会打印结果:

补充知识:springboot + @Async 实现异步方法之踩坑填坑

在使用@Async注解实现异步方法的时候,我们项目中实现了AsyncConfigurer接口来自定义线程池和异常处理。其中自定义线程池的代码如上图,异常处理项目中是自定义异常类实现AsyncUncaughtExceptionHandler 接口,这里未贴出代码。那么到底踩了什么坑呢?


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:解决SpringBoot中使用@Async注解失效的问题

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址