【Java异步】解决@Async注解,同类下调用不生效

在这里插入图片描述

个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~
个人主页:.29.的博客
学习社区:进去逛一逛~

在这里插入图片描述


一、@Async注解

@Async 是 Spring 框架中用于实现异步方法调用的注解

基本使用

1、启用异步支持 在配置类添加 @EnableAsync

   @Configuration
   @EnableAsync
   public class AsyncConfig {}

2、标注异步方法,在需要异步的方法条件 @Async

   @Service
   public class EmailService {
       @Async
       public void sendAsyncEmail(String content) {
           // 耗时操作(如发送邮件)
       }
   }

二、为什么同类下@Async不生效

根本原因

Spring 通过 动态代理 实现 @Async 的异步能力:

1、代理对象隔离

  • 当调用被 @Async 注解的方法时,实际调用的是代理对象的方法
  • 同类中的内部调用(如 this.method())直接访问原始对象,绕过了代理

2、代理类型差异

  • 如果使用 JDK 动态代理(基于接口),同类调用无法触发代理逻辑
  • 如果使用 CGLIB 代理(无接口类),同类调用同样受限于 this 调用

内部调用失效案例

@Service
public class OrderService {

    // ✅ 外部调用有效
    public void createOrder() {
        sendAsyncMsg(); // 通过代理对象调用
    }

    // ❌ 同类调用无效
    public void batchCreateOrders() {
        this.sendAsyncMsg(); // 直接调用原始对象方法
    }

    @Async
    public void sendAsyncMsg() {
        // 异步发送消息
    }
}

三、解决方案

方式1 异步方法拆分到不同类

// 异步操作单独成类
@Service
public class AsyncMessageService {
    @Async
    public void sendAsyncMsg() {
        // 异步逻辑
    }
}

// 主业务类通过依赖注入调用
@Service
@RequiredArgsConstructor
public class OrderService {
    private final AsyncMessageService asyncMessageService;

    public void batchCreateOrders() {
        asyncMessageService.sendAsyncMsg(); // 通过代理对象调用
    }
}

方式2 通过代理对象调用

  • 配置类添加配置exposeProxy = true
   @EnableAspectJAutoProxy(exposeProxy = true) // 配置类添加
   @Configuration
   @EnableAsync
   public class AsyncConfig {}
  • 同类下通过代理对象调用异步方法
@Service
public class OrderService {
	//AopContext上下文获取当前代理对象,调用异步方法
	public void batchCreateOrders() {
  	  ((OrderService) AopContext.currentProxy()).sendAsyncMsg();
	}

    @Async
    public void sendAsyncMsg() {
        // 异步逻辑
    }
}



在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

.29.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值