利用spring aop统一处理异常和打日志

spring aop的概念,很早就写博客介绍了,现在在工作中真正使用。

我们很容易写出的代码

我们很容易写出带有很多try catch 和 logger.warn(),logger.error()的代码,这样一个方法本来的业务逻辑只有5行,有了这些,代码就变成了10行或者更多行,如:

public ResultDTO<UserDTO> queryUserByCardId(String cardId) {ResultDTO<UserDTO> result = new ResultDTO<UserDTO>();StringBuilder log = new StringBuilder();log.append("queryUserByCardId:" + cardId);try {checkCardIdNotNull(cardId);StationUserDO userDO = userDAO.queryUserByCardId(cardId);UserDTO stationUserDTO = DataTypeConvertUtils.DOToDTO(userDO);result.setData(stationUserDTO);logger.warn(log.append(" result:").toString() + result);} catch (StationErrorCodeException e) {//logger.error(log.append("catch StationErrorCodeException!").toString(), e);result.setSuccess(false);result.setErrorCode(e.getErrorCode().getErrorCode());result.setErrorMessage(e.getErrorCode().getErrorMessage());} catch (Exception e) {logger.error(log.append("catch Exception!").toString(), e);result.setSuccess(false);result.setErrorCode(StationErrorCodeConstants.STA10001.getErrorCode());result.setErrorMessage(StationErrorCodeConstants.STA10001.getErrorMessage());}return result;
}

实际上,我们的业务逻辑就几行而已,中间却夹杂着那么多的异常处理代码及日志信息代码。


如何改进代码

我们可以使用springaop,做一个切面,这个切面专门做记录日志和异常处理的工作,这样就能减少重复代码。
代码如下:

@Override
public ResultDTO<StationUserDTO>queryUserByCardId(String cardId) {ResultDTO<StationUserDTO> result = new ResultDTO<StationUserDTO>();checkCardIdNotNull(cardId);StationUserDO userDO = stationUserDAO.queryStationUserByCardId(cardId);StationUserDTO stationUserDTO = DataTypeConvertUtils.DOToDTO(userDO);result.setData(stationUserDTO);return result;
}

我们在切面中做异常处理和记录日志:

@Aspect
public class CardServiceAspect {private final Logger logger = LoggerFactory.getLogger("card");// 切入点表达式按需配置@Pointcut("execution(* *.*(..)))")private void myPointcut() {}@Before("execution(* *.*(..)))")public void before(JoinPoint joinPoint) {String className = joinPoint.getTarget().getClass().getName();String methodName = joinPoint.getSignature().getName();logger.warn(className + "的" + methodName + "执行了");Object[] args = joinPoint.getArgs();StringBuilder log = new StringBuilder("入参为");for (Object arg : args) {log.append(arg + " ");}logger.warn(log.toString());}@AfterReturning(value = "execution(* *.*(..)))", returning = "returnVal")public void afterReturin(Object returnVal) {logger.warn("方法正常结束了,方法的返回值:" + returnVal);}@AfterThrowing(value = "StationCardServiceAspect.myPointcut()", throwing = "e")public void afterThrowing(Throwable e) {if (e instanceof StationErrorCodeException) {logger.error("通知中发现异常StationErrorCodeException", e);} else {logger.error("通知中发现未知异常", e);}}@Around(value = "StationCardServiceAspect.myPointcut()")public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {logger.warn("前置增强...");Object result = null;try {result = proceedingJoinPoint.proceed();} catch (Exception e) {ResultDTO resultDTO = new ResultDTO();if (e instanceof StationErrorCodeException) {StationErrorCodeException errorCodeException = (StationErrorCodeException) e;resultDTO.setSuccess(false);resultDTO.setErrorCode(errorCodeException.getErrorCode().getErrorCode());resultDTO.setErrorMessage(errorCodeException.getErrorCode().getErrorMessage());} else {resultDTO.setSuccess(false);resultDTO.setErrorCode(StationErrorCodeConstants.STA10001.getErrorCode());resultDTO.setErrorMessage(StationErrorCodeConstants.STA10001.getErrorMessage());}return resultDTO;}return result;}
}

然后我们在spring配置文件中配置切面

<!-- 配置切面的类 -->
<bean id="serviceAspect" class="com.lirui.StationCardServiceAspect"/>
<!-- 配置成注解方式寻找要被代理的对象 -->
<aop:aspectj-autoproxy/>

这样,我们就可以统一处理异常和日志了。


不足点

利用这种方式,只能打入参和出参,还有抛出异常时打异常日志,不能打方法运行中的中间值,目前我只能想到,方法中间值的日志,就是用原来的方式打出,不知道大家有没有什么好的方法。


spring aop的其他使用

推荐使用aspectJ来完成面向切面编程。我们还可以利用aop完成其他功能如记录程序运行时间等。

利用spring aop统一处理异常和打日志相关推荐

  1. 编程小白入门分享三:Spring AOP统一异常处理

    编程小白入门分享三:Spring AOP统一异常处理 参考文章: (1)编程小白入门分享三:Spring AOP统一异常处理 (2)https://www.cnblogs.com/lxk12345/p ...

  2. 利用Spring AOP 更新memcached 缓存策略的实现(一)

    本人参考文档:http://blog.csdn.net/ajun_studio/article/details/7343781 memcached批量删除解决方案:http://tech.ddvip. ...

  3. Spring AOP统一功能处理(切面、切点、连接点、通知)

    目录 一. AOP的一些前置知识 1.1什么是Aop 1.2 AOP的作用 1.3AOP基础组成 二.SpringAOP的实现 2.1添加SpringAOP框架支持 2.2定义切面(Aspect) 2 ...

  4. 利用Spring AOP与JAVA注解为系统增加日志功能

    Spring AOP一直是Spring的一个比较有特色的功能,利用它可以在现有的代码的任何地方,嵌入我们所想的逻辑功能,并且不需要改变我们现有的代码结构. 鉴于此,现在的系统已经完成了所有的功能的开发 ...

  5. 利用spring AOP注解实现日志管理

    最近刚接手一个项目,在项目的开始阶段,我们的架构师分配了个任务给我,让我利用spring的切面技术做一个日志管理的案例.要求很简单,就是需要记录:谁在什么时候对谁做了什么操作,同时在日志的描述中还要有 ...

  6. spring aop 统一捕获异常

    SpringAOP简介 面向切面编程(Aspect Oriented Programming)提供了另一种角度来思考程序的结构,通过这种方式弥补面向对象编程(Object Oriented Progr ...

  7. 简单好用!利用Spring AOP技术10分钟实现一个读写分离方案

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达今日推荐:2020年7月程序员工资统计,平均14357元,又跌了,扎心个人原创100W+访问量博客:点击前往,查看更多 作者 ...

  8. spring aop统一进行日常及异常的处理

    什么是AOP 以下摘自百度百科: 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.A ...

  9. dubbo全局异常处理_基于spring aop的dubbo异常统一处理

    dubbo统一异常处理,调用方只显示封装后的异常. 1.返回封装后的Exception 2.返回封装后的统一返回信息 import org.aspectj.lang.annotation.AfterT ...

最新文章

  1. 一名合格的运维工程师的历练之路
  2. 11JavaScript中的对象
  3. 以数据为核心的SOC3.0时代到来
  4. oracle USER 与 Schema 的关系与区别
  5. 17日直播预告丨Oracle 19c避雷经验分享
  6. 直接拿来用!超实用的Java数组技巧攻略
  7. php 是否支持json,php json 支持汉语
  8. 柯马机器人示教器编程_COMAU柯马机器人示教器无显示维修过程
  9. oracle执行cmd的实现方法
  10. java木马_Java校验上传图片文件是否含有木马的两种方式
  11. Java必知必会的问题
  12. delta对冲策略_期权的Delta对冲策略对比分析
  13. Python验证信用卡号的有效性(算法)(称为Luhn检测或者mod 10 检测)
  14. 函数空间一览:从线性空间到再生核希尔伯特空间
  15. 台湾国立大学郭彦甫Matlab教程笔记(6)user define function
  16. 1.网址推荐——专利下载
  17. 北航图像信号处理matlab实验,北航动态建模实验报告(matlab界面、动画).pdf
  18. Java系列技术之SSH整合+用户权限控制模型项目-钟洪发-专题视频课程
  19. Gitee+typora+picgo+插件,markdown图床配置,一键将markdown中本地图片上传至图床
  20. 使用开源软件替换现有的盗版软件

热门文章

  1. springMVC自定义全局异常
  2. 二十二、新人成才之路《做人七项原则 做一个节俭惜福的人》
  3. 浅谈25种设计模式(4/25)(此坑未填)
  4. centos 脚本基础练习1
  5. houdini + maya的pulldownit
  6. [译] ASP.NET 生命周期 – ASP.NET 上下文对象(六)
  7. 算法小论——第三章 又把新桃换旧符
  8. 一款基于jquery和css3的响应式二级导航菜单
  9. 《Two Dozen Short Lessons in Haskell》学习(八)- Function Types, Classes, and Polymorphism
  10. 批处理获取目录下所有文件名