首页 > 作文

springboot利用aop实现接口异步(进度条)的全过程

更新时间:2023-04-04 13:04:06 阅读: 评论:0

一、前言

在项目中发现有接口(excel导入数据)处理数据需要耗时比较长的时间,是因为数据量比较大,同时数据的校验需要耗费一定时间,决定使用一种通用的方法解决这个问题。

解决方案:通过aop使接口异步处理,前端轮询另外一个接口查询进度。

目标:

1接口上一个注解即可实现接口异步(优化:可以通过header参数动态控制是否异步)

2一个方法实现进度条的更新

二、时序图

三、功能演示

四、关键代码

controller

@enableasync是自已定义注解更新缓存进度asyncrvice.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缓存进度            asyncrvice.updatepercent(per);        }        integer b = 100;        return result.success(string.format("线程变量值:%s,100除以%s的结果是%s", requestholder.get(), num, b / num));    }

asyncaop

 impor柳州有什么大学t cn.hutool.core.util.idutil;import com.asyf.demo.common.result;import com.asyf.demo.common.pojo.requestholder;import com.asyf.demo.rvice.asyncrvice;import lombok.extern.slf4j.slf4j;import org.aspectj.lang.proceedingjoinpoin女性健康体检t;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.rvletrequestattributes; import javax.rvlet.http.httprvletrequest; @aspect@component@slf4jpublic class asyncaop {     @autowired    private asyncrvice asyncrvice;     @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        rvletrequestattributes rvletrequestattributes = (rvletrequestattributes) requestcontextholder.getrequestattributes();        httprvletrequest request = rvletrequestattributes.getrequest();        requestholder.t(request.getheader("dateformat"));        //异步消息        string id = idutil.simpleuuid();        asyncmsg asyncmsg = new asyncmsg();        asyncmsg.tid(id);        //异步返回值        object result = result.success(asyncmsg);        string requestholder = requestholder.get();         //异步执行        asyncrvice.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);    }}

asyncrvice

实现异步消息的更新

异步消息的进度信息传递通过本地线程与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.rvice.asyncrvice;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.rvice; import java.util.concurrent.timeunit; @rvice@slf4jp适合度蜜月的地方ublic class asyncrviceimpl implements asyncrvice {     @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.t(requestholder);                //异步消息线程变量-传送id到实际方法以便方法更新进度                asyncholder.t(asyncmsg);                //执行方法                try {                    redistemplate.opsforvalue().t(id, asyncmsg, 60, timeunit.minutes);                    object result = point.proceed();                    asyncmsg.tresult(result);                    asyncmsg.tstatus("0");                    redistemplate.opsforvalue().t(id, asyncmsg, 60, timeunit.minutes);                } catch (throwable throwable) {                    log.error(exceptionutil.stacktracetostring(throwable));                    asyncmsg.tstatus("-1");                    asyncmsg.tresult(throwable.getlocalizedmessage());                    redistemplate.opsforvalue().t(id, asyncmsg, 60, timeunit.minutes);                }            }        }).start();    }     @override    public void updatepercent(string per) {        asyncmsg asyncmsg = asyncholder.get();   has和have的用法     asyncmsg.tpercent(per);        redistemplate.opsforvalue().t(asyncmsg.getid(), asyncmsg, 60, timeunit.minutes);    } }

五、源码地址

java-demo: 存储代码示例 – gitee.com

总结

到此这篇关于springboot利用aop实现接口异步(进度条)的文章就介绍到这了,更多相关springboot aop实现接口异步内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

本文发布于:2023-04-04 13:04:05,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/a342bbe126768a2e4c84a652e646a481.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:springboot利用aop实现接口异步(进度条)的全过程.doc

本文 PDF 下载地址:springboot利用aop实现接口异步(进度条)的全过程.pdf

标签:接口   线程   进度   方法
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图