临汾山东漯河饰品美体美文
投稿投诉
美文创意
爱情通信
用品婚姻
爱好看病
美体软件
影音星座
瑜伽周边
星座办公
饰品塑形
搞笑减肥
幼儿两性
智家潮品
漯河衢州
兴义眉山
桂林阳泉
玉溪简阳
山东遂宁
永城新余
梧州洛阳
泸州温州
临汾清远
营口常熟
浙江大连
桐乡宜昌

SpringBoot项目如何优雅地实现操作日志记录

9月9日 长歌行投稿
  前言
  大家好,我是希留。
  在实际开发当中,对于某些关键业务,我们通常需要记录该操作的内容,一个操作调一次记录方法,每次还得去收集参数等等,会造成大量代码重复。我们希望代码中只有业务相关的操作,在项目中使用注解来完成此项功能。
  通常就是使用Spring中的AOP特性来实现的,那么在SpringBoot项目当中应该如何来实现呢?一、AOP是什么?
  AOP(AspectOrientedProgramming:向切编程),说起AOP,几乎学过Spring框架的人都知道,它是Spring的三大核心思想之一(IOC:控制反转,DI:依赖注入,AOP:面向切面编程)。能够将那些与业务关,却为业务模块所共同调的逻辑或责任(例如事务处理、志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。二、AOP做了什么?
  简单说来,AOP主要做三件事:1、在哪里切入,也就是日志记录等非业务代码在哪些业务代码中执行。2、在什么时候切入,是在业务代码执行前还是后。3、切入后做什么事情,比如权限校验,日志记录等。
  可以用一张图来理解:
  图上的一个核心术语的说明:Pointcut:切点,决定在何处切入业务代码中(即织入切面)。切点分为execution方式和annotation方式。execution方式:可以用路径表达式指定哪些类织入切面,annotation方式:可以指定被哪些注解修饰的代码织入切面。Advice:处理,包括处理时机和处理内容。处理内容就是要做什么事,比如校验权限和记录日志。处理时机就是在什么时机执行处理内容,分为前置处理(即业务代码执行前)、后置处理(业务代码执行后)等。Aspect:切面,即Pointcut和Advice。Jointpoint:连接点,是程序执行的一个点。例如,一个方法的执行或者一个异常的处理。在SpringAOP中,一个连接点总是代表一个方法执行。Weaving:织入,就是通过动态代理,在目标对象方法中执行处理内容的过程。三、实现步骤
  (1)自定义一个注解Log
  (2)创建一个切面类,切点设置为拦截标注Log的方法,截取传参,进行日志记录
  (3)将Log标注在接口上
  具体的实现步骤如下:1。添加AOP依赖
  代码如下(示例):dependencygroupIdorg。springframework。bootgroupIdspringbootstarteraopartifactIddependency2。自定义一个日志注解
  日志一般使用的是注解类型的切点表达式,我们先创建一个日志注解,当spring容器扫描到有此注解的方法就会进行增强。代码如下(示例):Target({ElementType。PARAMETER,ElementType。METHOD})注解放置的目标位置,PARAMETER:可用在参数上METHOD:可用在方法级别上Retention(RetentionPolicy。RUNTIME)指明修饰的注解的生存周期RUNTIME:运行级别保留DocumentedpublicinterfaceLog{模块Stringtitle()功能publicBusinessTypebusinessType()defaultBusinessType。OTHER;是否保存请求的参数publicbooleanisSaveRequestData()是否保存响应的参数publicbooleanisSaveResponseData()}3。切面声明
  申明一个切面类,并交给Spring容器管理。代码如下(示例):AspectComponentSlf4jpublicclassLogAspect{AutowiredprivateIXlOperLogServiceoperLogS处理完请求后执行paramjoinPoint切点AfterReturning(pointcutannotation(controllerLog),returningjsonResult)publicvoiddoAfterReturnibng(JoinPointjoinPoint,LogcontrollerLog,ObjectjsonResult){handleLog(joinPoint,controllerLog,null,jsonResult);}protectedvoidhandleLog(finalJoinPointjoinPoint,LogcontrollerLog,finalExceptione,ObjectjsonResult){try{获取当前的用户JwtUserloginUserSecurityUtils。getLoginUser();ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志a记录XlOperLogoperLognewXlOperLog();operLog。setStatus(0);请求的IP地址StringiPServletUtil。getClientIP(ServletUtils。getRequest());if(0:0:0:0:0:0:0:1。equals(iP)){iP127。0。0。1;}operLog。setOperIp(iP);operLog。setOperUrl(ServletUtils。getRequest()。getRequestURI());if(loginUser!null){operLog。setOperName(loginUser。getUsername());}if(e!null){operLog。setStatus(1);operLog。setErrorMsg(StringUtils。substring(e。getMessage(),0,2000));}设置方法名称StringclassNamejoinPoint。getTarget()。getClass()。getName();StringmethodNamejoinPoint。getSignature()。getName();operLog。setMethod(className。methodName());operLog。setRequestMethod(ServletUtils。getRequest()。getMethod());operLog。setOperTime(newDate());处理设置注解上的参数getControllerMethodDescription(joinPoint,controllerLog,operLog,jsonResult);保存数据库operLogService。save(operLog);}catch(Exceptionexp){log。error(异常信息:{},exp。getMessage());exp。printStackTrace();}}获取注解中对方法的描述信息用于Controller层注解paramlogahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志aparamoperLog操作ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志athrowsExceptionpublicvoidgetControllerMethodDescription(JoinPointjoinPoint,Loglog,XlOperLogoperLog,ObjectjsonResult)throwsException{设置操作业务类型operLog。setBusinessType(log。businessType()。ordinal());设置标题operLog。setTitle(log。title());是否需要保存request,参数和值if(log。isSaveRequestData()){设置参数的信息setRequestValue(joinPoint,operLog);}是否需要保存response,参数和值if(log。isSaveResponseData()StringUtils。isNotNull(jsonResult)){operLog。setJsonResult(StringUtils。substring(JSON。toJSONString(jsonResult),0,2000));}}获取请求的参数,放到log中paramoperLog操作ahrefhttps:www。bs178。comrizhitargetblankclassinfotextkey日志athrowsException异常privatevoidsetRequestValue(JoinPointjoinPoint,XlOperLogoperLog)throwsException{StringrequsetMethodoperLog。getRequestMethod();if(HttpMethod。PUT。name()。equals(requsetMethod)HttpMethod。POST。name()。equals(requsetMethod)){StringparsamsargsArrayToString(joinPoint。getArgs());operLog。setOperParam(StringUtils。substring(parsams,0,2000));}else{M?,?paramsMap(M?,?)ServletUtils。getRequest()。getAttribute(HandlerMapping。URITEMPLATEVARIABLESATTRIBUTE);operLog。setOperParam(StringUtils。substring(paramsMap。toString(),0,2000));}}参数拼装privateStringargsArrayToString(Object〔〕paramsArray){Sif(paramsArray!nullparamsArray。length0){for(Objectobject:paramsArray){不为空并且是不需要过滤的对象if(StringUtils。isNotNull(object)!isFilterObject(object)){ObjectjsonObjJSON。toJSON(object);paramsjsonObj。toString();}}}returnparams。trim();}判断是否需要过滤的对象。paramobject对象信息。return如果是需要过滤的对象,则返回否则返回false。SuppressWarnings(rawtypes)publicbooleanisFilterObject(finalObjectobject){C?clazzobject。getClass();if(clazz。isArray()){returnclazz。getComponentType()。isAssignableFrom(MultipartFile。class);}elseif(Collection。class。isAssignableFrom(clazz)){Collectioncollection(Collection)for(Objectvalue:collection){returnvalueinstanceofMultipartF}}elseif(Map。class。isAssignableFrom(clazz)){Mapmap(Map)for(Objectvalue:map。entrySet()){Map。Entryentry(Map。Entry)returnentry。getValue()instanceofMultipartF}}returnobjectinstanceofMultipartFileobjectinstanceofHttpServletRequestobjectinstanceofHttpServletResponseobjectinstanceofBindingR}}4。标注在接口上
  将自定义注解标注在需要记录操作日志的接口上,代码如下(示例):Log(title代码生成,businessTypeBusinessType。GENCODE)ApiOperation(value批量生成代码)GetMapping(downloadbatch)publicvoidbatchGenCode(HttpServletResponseresponse,Stringtables)throwsIOException{String〔〕tableNamesConvert。toStrArray(tables);byte〔〕datagenTableService。downloadCode(tableNames);genCode(response,data);}5。实现的效果
  执行相关操作就会记录日志,记录了一些基础信息存在数据表里。
  总结
  好了,以上就是本篇文章的主要内容了,本文主要讲述了使用SpringAOP来实现操作日志的记录,欢迎评论区留言,说说你们的项目中是如何实现操作日志的。
  若觉得本文对您有帮助的话,还不忘点赞评论关注,支持一波哟
投诉 评论

还是娘家亲!雷记为威少鸣不平全力奉献的那位承担了全部责任直播吧7月17日讯据此前报道,湖人内部正努力于尽快找到威少问题的解决方案,目前的思路是用他换回欧文。雷霆随队记者BrandonRahbar发推为威少鸣了不平。Brando……墓地陵园公园景点将成热点北京清明假期交通出行提示请收好清明假期即将到来,在北京,墓地陵园、高速公路、公园景点将成为出行热点,以下交通出行提示请收好1各墓地陵园周边交通压力较为突出1各墓地陵园周边交通压力较为突出清……妈妈不生气,孩子才争气打卡不生气妈妈第2期,目标更新100期今日学习内容,什么样的孩子容易成为窝囊废?被吼大被长期语言暴力的孩子。他的自卑是骨子里的,一辈子都很难治愈。千万不要再用指责吼叫的方式去跟孩子沟通。高情商的家……达到光速会看到什么?科学家达到光速后,时间将不复存在速度是探索世界最快的方式,从古至今,人类一直都在提升自己的速度,古时候,由于人类的科技有限,人民出行基本上都是依靠步行或者是马车,所以很多人一辈子都没有走出方圆百里,不过随着人……SpringBoot项目如何优雅地实现操作日志记录前言大家好,我是希留。在实际开发当中,对于某些关键业务,我们通常需要记录该操作的内容,一个操作调一次记录方法,每次还得去收集参数等等,会造成大量代码重复。我们希望代……2022切尔西花园展获奖作品38款享誉世界的英国RHS切尔西花展于2022年5月24日至28日开展本届以wildandnatural为主题将绿色空间变成野生动物友好的避风港为大家精选38……第一次做全身精油按摩的真实感受入了冬,已经零下十几度了。身上格外干燥,于是决定来体验人生第一次spa按摩,很期待又害羞,整体来说确实很舒服,但是有些手法不太专业,不太到位。第一次全身spa体验我……三星GalaxyBook3Ultra笔记本真机曝光,对标苹果IT之家1月17日消息,几个月前有消息称,三星将在GalaxyBook3笔记本系列中增加一款Ultra机型,现在这款笔记本的真机图已经曝光。三星似乎已经通过了Galaxy……首次发现,1910年的绍兴绝版旧照,古越胜地,水韵之城的会稽这是一组拍摄于1910年左右的浙江绍兴的绝版老照片,照片来源于1910年左右出版的一本摄影集。这本摄影集是商务印书馆根据当时的摄影人拍摄的晚清各地名胜古迹的照片,结集出版发行了……中国足球的唯一希望开始出现(附现场图集)昨晚进行了中超第32轮的较量,成都蓉城主场对阵武汉三镇的比赛格外引人瞩目。不仅因为本场比赛事关争冠形势,更在于这是主队成都蓉城在新主场凤凰山专业球场的首秀。在疫情肆虐的三年里、……孩子身上长湿疹怎么办?又该如何预防呢?湿疹是一种过敏性皮肤病,一旦发痒很多孩子都忍受不了,那么怎样缓解瘙痒发作时的瘙痒问题呢,下面是我为大家整理的关于孩子身上长湿疹痒怎么解决,如果喜欢可以分享给身边的朋友喔!……湖南常宁经济建设佳音频传,又喜迎南衡高铁过境的好消息湖南省常宁市新貌湖南工业要取得大发展,离不开衡阳工业的重新崛起,因为,它是湖南省的两个省域副中心城市之一。在衡阳,基本上是县域经济强于市区。县域中,工业建设的佼佼者……
巴甲弗鲁米嫩塞VS塞阿拉,巴西国家队最水9号告别战人民日报每日金句摘抄2001年2021年,我们使用过的手机脾不足痰多,肺不足汗多,血不足梦多,3个中成药,化痰止汗助眠维密天使们穿环保内衣大秀魔鬼身材!太性感火辣了谈谈王思聪和李易峰的区别地下城与勇士手游65版本准备工作做好这些材料储备今年最后悔的,就是没有梭哈煤炭每天喝一杯咖啡,对健康是好是坏?49万人研究结果,给出答案无指纹也能开,静脉检测更安全,鹿客新品S50智能锁评测买手机的三个忠告,处理器可以不用看了,记住这三点,体验不会差叶倩文坐镇声生不息,穿露背裙打扮清凉好用力,姜还是老的辣无私无畏读不尽的周恩来交友语录有哪些投资30亿,目标票房150亿,黄渤这部新片,会成为暑期档爆款韩式发型哪个最好看?韩国明星演绎修颜蓬松长发手机带娃有风险,陪伴方为上策操作系统GUI进化史车辆自燃险的赔偿范围是什么《小枕头》小班音乐教案工程合同离校申请书福克纳《喧哗与骚动》的主要内容梗概是什么简介含笑的养殖方法(含笑树种植方法)

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找