SpringBoot之异步调用@Async

场景:微信公众号授权页面,公众号所有者扫码授权时,拉取公众号下的粉丝信息,完成后跳转至授权成功页面。

问题:当粉丝数量很大的时候,拉取用户信息(包括网络请求)耗时很长,授权页面会因为请求超时挂掉。(很多耗时操作都要考虑到用户体验,先返回授权成功页面,耗时操作在异步执行)

解决方法:异步执行耗时的拉取用户信息操作。SpringBoot中直接可以@Async注解实现异步调用。

@Controller
@RequestMapping("/open/auth")
public class AuthCallbackController extends SuperController {   

    @RequestMapping("/callbacktest")
    public String callback()throws Exception{
        new CoreTask().task1();
        new CoreTask().task2();
        new CoreTask().task3();
        return "auth/authSuccess";
    }

}

CoreTask类,执行测试的三个方法上加上注解@Async:

@Component
public class CoreTask {
    @Async
    public void task1()throws Exception{
        Thread.sleep(1000);
        System.out.println("我是任务1");
    }
    @Async
    public void task2()throws Exception{
        Thread.sleep(2000);
        System.out.println("我是任务2");
    }
    @Async
    public void task3()throws Exception{
        Thread.sleep(3000);
        System.out.println("我是任务3");
    }
}

SpringBoot启动主类Application类也要加上注解@EnableAsync

启动项目,通过浏览器访问open/auth。

异步执行不是按照顺序依次执行的,而且授权成功页面不用等方法都执行完才请求到。

访问结果依然是依次执行,授权成功页面也是方法执行完才显示。

百度找解决方法。


异步并没有执行!

难道是代码写错了?反复检查了好几遍,并没有发现什么明显错误,想起spring对@Transactional注解时也有类似问题,spring扫描时具有@Transactional注解方法的类时,是生成一个代理类,由代理类去开启关闭事务,而在同一个类中,方法调用是在类体内执行的,spring无法截获这个方法调用。

百度找到的这个答案和我遇到的问题并不一样,他遇到的这种情况是在当前的类中调用异步方法。

扫描二维码关注公众号,回复: 475424 查看本文章

在同一个类中,方法调用是在类体内执行的,spring无法截获这个方法调用。

我突然想起来我是new来实例化CoreTask类的,然后调用其中的异步方法。问题可能出在这里,spring无法拦截实例化的这个类的方法调用。

于是,在Controller中添加,然后调用异步方法:

@Autowired
private CoreTask coreTask;

------------------------------

coreTask.task1();
coreTask.task2();
coreTask.task3();

重启,异步执行成功。授权成功页面在请求的第一时间就刷新出来,并没有等到异步方法都执行完。

猜你喜欢

转载自blog.csdn.net/kanglovejava/article/details/79285389