springboot怎么利用aop实现接口异步
发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,小编给大家分享一下springboot怎么利用aop实现接口异步,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!一、前言在项目中发现有接口(excel导入数据)处理数据需要耗时比较长的
千家信息网最后更新 2026年11月01日springboot怎么利用aop实现接口异步
小编给大家分享一下springboot怎么利用aop实现接口异步,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!
一、前言
在项目中发现有接口(excel导入数据)处理数据需要耗时比较长的时间,是因为数据量比较大,同时数据的校验需要耗费一定时间,决定使用一种通用的方法解决这个问题。
解决方案:通过aop使接口异步处理,前端轮询另外一个接口查询进度。
目标:
1接口上一个注解即可实现接口异步(优化:可以通过header参数动态控制是否异步)
2一个方法实现进度条的更新
二、时序图

三、功能演示
四、关键代码
Controller
@EnableAsync是自已定义注解更新缓存进度asyncService.updatePercent(per);
@EnableAsync @RequestMapping(value = "test", method = RequestMethod.POST) @ApiOperation(value = "接口测试") @ApiImplicitParams({ @ApiImplicitParam(name = "num", value = "数字", required = true, dataType = "int", paramType = "query", defaultValue = "1") }) public Object demo(Integer num) throws InterruptedException { for (int i = 0; i < 15; i++) { Thread.sleep(1000); //计算百分比 String per = BigDecimal.valueOf(i).divide(BigDecimal.valueOf(15), 2, RoundingMode.HALF_DOWN).toString(); //更新redis缓存进度 asyncService.updatePercent(per); } Integer b = 100; return Result.success(String.format("线程变量值:%s,100除以%s的结果是%s", RequestHolder.get(), num, b / num)); }AsyncAop
import cn.hutool.core.util.IdUtil;import com.asyf.demo.common.Result;import com.asyf.demo.common.pojo.RequestHolder;import com.asyf.demo.service.AsyncService;import lombok.extern.slf4j.Slf4j;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import org.aspectj.lang.reflect.MethodSignature;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; @Aspect@Component@Slf4jpublic class AsyncAop { @Autowired private AsyncService asyncService; @Pointcut("@annotation(com.asyf.demo.common.aop.EnableAsync)") public void costTimePointCut() { } @Around("costTimePointCut()") public Object around(ProceedingJoinPoint point) throws Throwable { long beginTime = System.currentTimeMillis(); //请求header ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = servletRequestAttributes.getRequest(); RequestHolder.set(request.getHeader("dateFormat")); //异步消息 String id = IdUtil.simpleUUID(); AsyncMsg asyncMsg = new AsyncMsg(); asyncMsg.setId(id); //异步返回值 Object result = Result.success(asyncMsg); String requestHolder = RequestHolder.get(); //异步执行 asyncService.async(requestHolder, asyncMsg, point); //执行时长(毫秒) long time = System.currentTimeMillis() - beginTime; logCostTime(point, time); return result; } private void logCostTime(ProceedingJoinPoint point, long time) { MethodSignature signature = (MethodSignature) point.getSignature(); String className = point.getTarget().getClass().getName(); String methodName = signature.getName(); log.info("class:{} method:{} 耗时:{}ms", className, methodName, time); }}AsyncService
实现异步消息的更新
异步消息的进度信息传递通过本地线程与redis实现
import cn.hutool.core.exceptions.ExceptionUtil;import com.asyf.demo.common.aop.AsyncMsg;import com.asyf.demo.common.pojo.AsyncHolder;import com.asyf.demo.common.pojo.RequestHolder;import com.asyf.demo.service.AsyncService;import lombok.extern.slf4j.Slf4j;import org.aspectj.lang.ProceedingJoinPoint;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.stereotype.Service; import java.util.concurrent.TimeUnit; @Service@Slf4jpublic class AsyncServiceImpl implements AsyncService { @Autowired private RedisTemplate redisTemplate; @Override public void async(String requestHolder, AsyncMsg asyncMsg, ProceedingJoinPoint point) { new Thread(new Runnable() { @Override public void run() { String id = asyncMsg.getId(); //请求线程变量-传递请求线程参数 RequestHolder.set(requestHolder); //异步消息线程变量-传送id到实际方法以便方法更新进度 AsyncHolder.set(asyncMsg); //执行方法 try { redisTemplate.opsForValue().set(id, asyncMsg, 60, TimeUnit.MINUTES); Object result = point.proceed(); asyncMsg.setResult(result); asyncMsg.setStatus("0"); redisTemplate.opsForValue().set(id, asyncMsg, 60, TimeUnit.MINUTES); } catch (Throwable throwable) { log.error(ExceptionUtil.stacktraceToString(throwable)); asyncMsg.setStatus("-1"); asyncMsg.setResult(throwable.getLocalizedMessage()); redisTemplate.opsForValue().set(id, asyncMsg, 60, TimeUnit.MINUTES); } } }).start(); } @Override public void updatePercent(String per) { AsyncMsg asyncMsg = AsyncHolder.get(); asyncMsg.setPercent(per); redisTemplate.opsForValue().set(asyncMsg.getId(), asyncMsg, 60, TimeUnit.MINUTES); } }看完了这篇文章,相信你对"springboot怎么利用aop实现接口异步"有了一定的了解,如果想了解更多相关知识,欢迎关注行业资讯频道,感谢各位的阅读!
接口
进度
方法
线程
更新
数据
消息
参数
变量
时间
注解
篇文章
缓存
处理
代码
信息
关键
前端
前言
功能
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
互联网科技官网
互联网是不是新科技
互联网巨头反垄断金融科技
互联网 科技创新
互联网科技作文
未来的互联网科技
深圳齐家互联网科技
上海致骋互联网科技
唐信互联网科技 大连
菲比寻常互联网科技
掌上梦互联网科技
深圳期待互联网科技
互联网对科技的发展
互联网公司科技股
深圳市优智互联网科技有限公司
无锡工业互联网科技有限公司
张召忠谈中国互联网科技
南京一网一红互联网科技有限公司
互联网领先科技活动
易租星互联网科技有限公司
美国互联网科技巨头监管
深圳科技互联网
互联网金融 科技
广西互联网科技公司
博兴的互联网电子科技公司
福建科技产业互联网发展
杭州壁岐互联网科技有限公司
云南省自由互联网科技有限公司
福建互联网展示科技馆设计
黑龙江互联网科技公司