SpringBoot @Async 异步注解无效

解决思路:

  1. 先查看启动类是否加上 @EnableAsync 注解,如果没有,就加上该注解再重新启动
  2. 查看异步方法的调用方式是否正确

@Async的调用涉及到动态代理,如果直接将需要异步操作的方法写到业务类中,业务类直接调用,则执行逻辑不会走到代理类,异步就会失效
例如用下面的方式调用(错误演示),异步就不会生效,打印的结果必定为:1 2 3

@SpringBootApplication
@EnableAsync
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}


@Service
class AAAService{
    public void AAAMethod(){
        System.out.println("1");
        asyncMethod();
        System.out.println("3");
    }
    
    @Async
    public void asyncMethod(){
        System.out.println("2");
    }
}

因此需要将 @Async 注解的方法单独拿出来封装到一个类中,再将这个类注入到业务类中,业务类通过这个类来调用异步方法


@SpringBootApplication
@EnableAsync
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

@Service
class AAAService{

    @Autowire
    private AsyncManage asyncManage;

    public void AAAMethod(){
        System.out.println("1");
        asyncManage.asyncMethod();
        System.out.println("3");
    }
}

@Component
class AsyncManage{
    @Async
    public void asyncMethod(){
        System.out.println("2");
    }
}

输出结果为:1 3 2 (如果异步线程执行的很快,也有很小的概率是1 2 3)

(代码存手打,不知道有没有啥问题,能看懂意思就行...)

另外在网上也看到一些失效原因分析,贴过来看一下:
1.异步方法使用注解@Async的返回值只能为void或者Future。
2.没有走Spring的代理类。因为@Transactional和@Async注解的实现都是基于Spring的AOP,而AOP的实现是基于动态代理模式实现的。那么注解失效的原因就很明显了,有可能因为调用方法的是对象本身而不是代理对象,因为没有经过Spring容器。
https://blog.csdn.net/YoungLee16/article/details/88398045

猜你喜欢

转载自www.cnblogs.com/codeclock/p/12625474.html