首页 > 作文

在springboot中使用AOP进行全局日志记录

更新时间:2023-04-03 22:36:56 阅读: 评论:0

目录
前言1、 spring aop 是什么?2、spring aop 能做什么?3、spring aop 我能用 aop 解决什么问题?一、引入依赖,增加自定义注解1、引入 maven 依赖2、增加自定义注解 operationlog二、为自定义注解编写切面实现三、使用自定义日志注解

前言

此前项目上需要对用户的操作进行日志记录,以便后续追踪问题,所以就学习了使用 spring aop 来进行日志记录。

1、 spring aop 是什么?

spring 的两大核心就是 ioc 和 aop,aop 是 spring 框架面向切面的编程思想,aop是横切性的技术,将涉及多业务流程的通用功能抽取并单独封装,形成独立的切面,再将这些切面横向切入到业务流程指定的位置中。

2、spring aop 能做什么?

aop 主要是从切面入手,将日志记录、安全控制、事务处理、全局异常处理等全局功能从我们的业务逻辑代码中划分出来。

3、spring aop 我能用 aop 解决什么问题?

正好我这边需要做一个全局的日志,如果每个方法都去写日志记录,这样代码量非常大,而且代码繁琐冗余,全局记录的话,只需要在方法上增加一个注解就可以实现日志记录。

好了,不多bb,直接上代码实现

一、引入依赖,增加自定义注解

1、引入 maven 依赖

        <!--利用 aop 做操作日志记录-->        <dependency>            <groupid>org.springframework.boot</groupid>            <artifactid>spring-boot-starter-aop</artifactid>        </dependency>

2、增加自定义注解 operationlog

@target(elementtype.method) //注解放置的目标位置,method是可注解在方法级别上@retention(retentionpolicy.runtime) //注解执行阶段@documentedpublic @interface operationlog {    string operdesc() default "";  // 操作说明}

二、为自定义注解编写切面实现

@aspect //标识一个切面类@componentpublic class operationlogaspect {private static final logger logger = loggerfactory.getlogger(operationlogaspect.class);@autowiredprivate operatelogsrvice operatelogsrvice;@autowiredprivate sysurrvice urrvice;/*** 设置操作日志切入点 记录操作日志 在注解的位置切入代码*/@pointcut("@annotation(com.wxw.annotation.operationlog)")public void operlogpoincut() {}/*** 正常返回通知,拦截用户操作日志,连接点正常执行完成后执行, 如果连接点抛出异常,则不会执行** @param joinpoint 切入点* @param keys      返回结果*/@afterreturning(value = "operlogpoincut()", returning = "keys")public void saveoperlog(joinpoint joinpoint, object keys) {// 获取requestattributesrequestattributes requestattributes = requestcontextholder.getrequestattributes();// 从获取requestattributes中获取httprvletrequest的信息httprvletrequest request = (httprvletrequest) requestattributes.resolvereference唯美清新图片(requestattributes.reference_request);operatelogs operlog = new operatelogs();try {// 从切面织入点处通过反射机制获取织入点处的方法methodsignature signature = (methodsignature) joinpoint.getsignature();// 获取切入点所在的方法method method = signature.getmethod();// 获取操作operationlog oplog = method.getannotation(operationlog.class);if (oplog != null) {string operdesc = oplog.operdesc();operlog.tfdescript(operdesc); // 操作描述}// 获取请求的类名string classname = joinpoint.gettarget().getclass().getname();// 获取请求的方法名string methodname = method.getname();methodname = classname + "." + methodname;operlog.tfrequestmethod(methodname); // 请求方法// 请求的参数object[] arguments = joinpoint.getargs();//判断参数数组是否为空stream<?> stream = arrayutils.impty(arguments) ? stream.empty() :  arrays.aslist(arguments).stream();//过滤 joinpoint.getargs()返回的数组中携带有request或者respon对象list<object> logargs = stream.filter(arg -> (!(arg instanceof httprvletrequest) && !(arg instanceof httprvletrespon))).collect(collectors.tolist());// 先将参数所在的list 转换成json 数组jsonarray jsonarray = jsonarray.pararray(json.tojsonstring(logargs));//再转 json 字符串string params = jsonarray.tojsonstring();operlog.tfrequestdata(params); // 请求参数operlog.tfrespondata(json.tojsonstring(keys)); // 返回结果sysur ur = getur();oper快乐大本营几点播log.tfoptby(ur != null ? ur.getfurid() : 0); // 请求用户idoperlog.tfoptname(ur != null ? ur.getfurcode() : "admin"); // 请求用户名称operlog.tfopton(new date()); // 创建时间operlog.tfip(getip()); // 请求ipoperlog.tfrequesturl(request.getrequesturi()); // 请求urioperatelogsrvice.savelnx原函数(operlog);} catch (exception e) {e.printstacktrace();}}/*** 异常返回通知,用于拦截异常日志信息 连接点抛出异常后执行** @param joinpoint 切入点* @param e         异常信息*/@afterthrowing(pointcut = "operlogpoincut()", throwing = "e")public void saveexceptionlog(joinpoint joinpoint, throwable e) {// 获取requestattributesrequestattributes requestattributes = reque一百样东西stcontextholder.getrequestattributes();// 从获取requestattributes中获取httprvletrequest的信息httprvletrequest request = (httprvletrequest) requestattributes.resolvereference(requestattributes.reference_request);operatelogs operlog = new operatelogs();try {// 从切面织入点处通过反射机制获取织入点处的方法methodsignature signature = (methodsignature) joinpoint.getsignature();// 获取切入点所在的方法method method = signature.getmethod();// 获取请求的类名string classname = joinpoint.gettarget().getclass().getname();// 获取请求的方法名string methodname = method.getname();methodname = classname + "." + methodname;// 请求的参数object[] arguments = joinpoint.getargs();//判断参数数组是否为空stream<?> stream = arrayutils.impty(arguments) ? stream.empty() :  arrays.aslist(arguments).stream();//过滤 joinpoint.getargs()返回的数组中携带有request或者respon对象list<object> logargs = stream.filter(arg -> (!(arg instanceof httprvletrequest) && !(arg instanceof httprvletrespon))).collect(collectors.tolist());// 先将参数所在的list 转换成json 数组jsonarray jsonarray = jsonarray.pararray(json.tojsonstring(logargs));//再转 json 字符串string params = jsonarray.tojsonstring();operlog.tfrequestdata(params); // 请求参数operlog.tfrequestmethod(methodname); // 请求方法名operlog.tfexceptionname(e.getclass().getname()); // 异常名称operlog.tfrespondata(stacktracetostring(e.getclass().getname(), e.getmessage(), e.getstacktrace())); // 异常信息sysur ur = getur();operlog.tfoptby(ur != null ? ur.getfurid() : 0); // 请求用户idoperlog.tfoptname(ur != null ? ur.getfurcode() : "admin"); // 请求用户名称operlog.tfopton(new date()); // 创建时间operlog.tfrequesturl(request.getrequesturi()); // 请求urioperlog.tfip(getip()); // 请求ipoperatelogsrvice.save(operlog);} catch (exception e2) {e2.printstacktrace();}}/*** 获取用户信息,由于我这边 token 是使用 jwt 生成,所以可以从中获取用户id,再根据id获取用户数据** @return*/public sysur getur() {httprvletrequest request = ((rvletrequestattributes) requestcontextholder.getrequestattributes()).getrequest();sysur sysur = null;string token = request.getheader("token");// 从 http 请求头中取出 tokenif(token != null){// 获取 token 中的 ur idstring urid = jwt.decode(token).getaudience().get(0);sysur = urrvice.getone(new querywrapper<sysur>().lambda().eq(sysur::getfurid,u事业单位绩效考核表rid));}return sysur;}/*** 获取ip** @return*/public string getip() {//获得本机的ip和名称inetaddress addr = null;try {addr = inetaddress.getlocalhost();} catch (unknownhostexception e) {throw new customexception(500,e.getmessage());}string ip = addr.gethostaddress();//      string hostname = addr.gethostname();return ip;}/*** 转换异常信息为字符串** @param exceptionname    异常名称* @param exceptionmessage 异常信息* @param elements         堆栈信息*/public string stacktracetostring(string exceptionname, string exceptionmessage, stacktraceelement[] elements) {stringbuffer strbuff = new stringbuffer();for (stacktraceelement stet : elements) {strbuff.append(stet + "\n");}string message = exceptionname + ":" + exceptionmessage + "\n\t" + strbuff.tostring();return message;}}

三、使用自定义日志注解

将自定义注解加在方法上,请求方法之后,就可以将方法的日志记录到自己的数据库里面了。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持www.887551.com。

本文发布于:2023-04-03 22:36:55,感谢您对本站的认可!

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

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

本文word下载地址:在springboot中使用AOP进行全局日志记录.doc

本文 PDF 下载地址:在springboot中使用AOP进行全局日志记录.pdf

标签:注解   切面   自定义   日志
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图