当前位置: 首页 > 编程日记 > 正文

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

利用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完成其他功能如记录程序运行时间等。

相关文章:

Matlab与线性代数 -- 矩阵的重组5

本图文详细介绍了矩阵重组的Matlab命令reshape()。

windows XP下Python2.7包管理工具安装-setuptool,pip、distribute、nose、virtualenv

在Python开发中为了对项目进行管理和调试。必须安装一些特定的软件包。据说业内这个叫做yak shaving-做一个非常酷非常绚丽的Python项目之前&#xff0c;必须做的一些枯燥无味的准备工作。本文介绍了setuptool。pip、distribute、nose、virtualenv的安装。 1&#xff0c;pytho…

黑客必知的SQL语句 黑客知道,程序员必知

SQL语句先前写的时候&#xff0c;很容易把一些特殊的用法忘记&#xff0c;我特此整理了一下SQL语句操作。 一、基础 1、说明&#xff1a;创建数据库 Create DATABASE database-name 2、说明&#xff1a;删除数据库 drop database dbname 3、说明&#xff1a;备份sql server --…

AutowireCapableBeanFactory,实现不必配置xml文件,动态加载bean

场景 今天遇见一个问题&#xff0c;如何能做到一个类&#xff0c;没有在spring的配置文件中配置&#xff0c;但是还能通过某种方式加载进来。通过查看一些代码&#xff0c;查看stackoverflow&#xff0c;了解了一些知识。 如果一个类并没有在applicationContext中配置我们可以…

[导入]如何理解Return的返回值?

如何理解Return的返回值&#xff1f; 问题&#xff1a; 在创建和录制脚本的时候&#xff0c;发现在脚本vuser_init、Action、vuser_end三部分&#xff0c;都会有一条“return 0;”语句&#xff0c;那么我们平时在编写脚本时如何应用return语句&#xff0c;return不同的返回值又…

如何利用神经网络结合遗传算法进行非线性函数极值寻优(2)

如何利用神经网络结合遗传算法进行非线性函数极值寻优

自己亲自写的两本linux资料,免费下载,pdf文档

第一本是我写的韩顺平老师解说的linux视频的笔记&#xff0c;该视频原本有21讲&#xff0c;可是我始终没有找到当中的17、18讲。可是其它部分我感觉及记录的还是蛮认真的。该套视频解说的非常基础&#xff0c;因此我的这本笔记也非常基础。这里是免积分在csdn上的下载地址&…

深入理解Java:SimpleDateFormat安全的时间格式化

转自&#xff1a;http://www.cnblogs.com/peida/archive/2013/05/31/3070790.html 想必大家对SimpleDateFormat并不陌生。SimpleDateFormat 是 Java 中一个非常常用的类&#xff0c;该类用来对日期字符串进行解析和格式化输出&#xff0c;但如果使用不小心会导致非常微妙和难以…

如何提高增加包含大量记录的表的主键字段的效率

如何提高增加包含大量记录的表的主键字段的效率 LazyBee 1 问题的提出&#xff1a; 在给客户升级数据库系统时&#xff0c;由于报表的需要&#xff0c;系统中每一个表都需要有主键字段。系统审计表自然也有这个要求—需要增加一个identify的字段&#xff0c;但这个表中有2000多…

${pageContext.request.contextPath} JSP取得绝对路径

在使用的时候可以使用${pageContext.request.contextPath}&#xff0c;也同时可以使用<%request.getContextPath()%>达到同样的效果&#xff0c;同时&#xff0c;也可以将${pageContext.request.contextPath}&#xff0c;放入一个JSP文件中&#xff0c;将用C&#xff1a;…

Matlab与线性代数 -- 矩阵的水平连接和垂直连接

本图文详细介绍了Matlab中矩阵的水平连接和垂直连接。

Matlab与线性代数 -- 矩阵的复制

本图文详细介绍了Matlab中矩阵复制函数repmat(A,m,n)。

用C#实现抽象工厂模式

大家都知道&#xff0c;在开发中&#xff0c;如果用好了某种模式&#xff0c;那效率…… 嘿嘿 我就不说了 进入正题吧&#xff1a; 以下都为源代码&#xff0c;可直接拷贝&#xff0c;然后自己研究 由于是讲解&#xff0c;所以只涉及基本的架构 项目名为&#xff1a;Ab…

树莓派 raspberry安全关机命令重启命令

树莓派可以通过下面几个命令来实现安全关机&#xff1a;sudo shutdown -h now sudo halt sudo poweroff sudo init 0上面四行代码都可以&#xff0c;执行一行都可以安全关机, ^_^树莓派重启 定时重启方法&#xff1a;sudo reboot shutdown -r now shutdown -r 04:00:00 #定时重…

jps命令(Java Virtual Machine Process Status Tool)(转)

1、介绍 用来查看基于HotSpot的JVM里面中&#xff0c;所有具有访问权限的Java进程的具体状态, 包括进程ID&#xff0c;进程启动的路径及启动参数等等&#xff0c;与unix上的ps类似&#xff0c;只不过jps是用来显示java进程&#xff0c;可以把jps理解为ps的一个子集。 使用jps时…

使用 Smartmontools 检测硬盘坏道

2019独角兽企业重金招聘Python工程师标准>>> 在这篇文章中&#xff0c;我们通过几个必要的步骤&#xff0c;使用特定的磁盘扫描工具让你能够判断 Linux 磁盘或闪存是否存在坏道。 在Linux上使用坏块工具检查坏道 坏块工具可以让用户扫描设备检查坏道或坏块&#xff…

如何使用Github管理自己的代码

本文介绍了使用Github管理代码的基本操作方法。由LSGO软件技术团队的安晟提供。

javassist 初步学习

javassist简介 javassist可以对一个已经编译好了的.class文件的字节码进行改动&#xff0c;比如说我可以为一个类添加一个方法&#xff0c;添加一个属性&#xff0c;也可以修改一个方法等&#xff0c;还可以对一个方法&#xff0c;异常进行拦截等。 我们常用到的动态特性主要…

.NET环境下有关打印页面设置、打印机设置、打印预览对话框的实现

原文:.NET环境下有关打印页面设置、打印机设置、打印预览对话框的实现我个人认为&#xff0c;开发MIS&#xff0c;首先就得解决网格的问题,而开发工具为我们提供了如DataGrid、MSHFlexGrid的控件。其次&#xff0c;是打印的问题&#xff0c;将业务单据与数据报表打印出来。可想…

Silverlight 2 beta 2 中目前不支持共享 WCF 的客户端类型

在调用多个 WCF Service 的时候经常会遇到的一个问题是&#xff0c;某些同样的类型因为在不同的 Service 里用到&#xff0c;就被重复生成了好几个版本的代理类型&#xff0c;分别处在不同的名称空间下。这样&#xff0c;如果一个操作需要同时调用几个 Service&#xff0c;就会…

Matlab与线性代数 -- 逆矩阵

本微信图文详细介绍了Matlab中各种求逆矩阵的方法。

使用intellij idea制作可执行jar文件

可执行jar文件 一个可执行的 jar文件是一个自包含的 Java 应用程序&#xff0c;它存储在特别配置的 JAR 文件中&#xff0c;可以由 JVM 直接执行它而无需事先提取文件或者设置类路径。要运行存储在非可执行的 JAR 中的应用程序&#xff0c;必须将它加入到您的类路径中&#xf…

c# 一些控件常用屬性

Form&#xff1a;ControlBox&#xff1a;移除窗體按鈕(最大化、最小化、關閉組&#xff09;&#xff0c;並從左側移除「系統菜單」Opacity&#xff1a;控制窗體透明度ActiveControl&#xff1a;指出窗體上當前哪一個擦傷擁有焦點BackColor&#xff1a;窗體中任何文本和圖形的默…

centos设置固定IP方法

首先网络模式设为桥接 [rootcentos64 ~]# vi /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICEeth0HWADDR00:0C:29:80:9D:41TYPEEthernetUUID29784981-a8cc-4405-8923-264df546350eONBOOTyesNM_CONTROLLEDyesBOOTPROTOstatic #设为静态的IPADDR192.168.0.99 #设置固定ipNETMA…

如何利用离散Hopfield神经网络进行数字识别(1)

如何利用离散Hopfield神经网络进行数字识别&#xff0c;代码部分。

You can't specify target table for update in FROM clause

今天使用mysql,写出一个sql语句&#xff1a; update service_re set is_deleted0 where id(select id from service_re where p_id21000122321 limit 1);执行这样的sql会报一个异常&#xff1a; You cant specify target table for update in FROM clause 查了资料&#xf…

在C# Express 2005中配置 NUnit

在C# Express 2005中配置 NUnit www.cnblogs.com/Pamigo/ 2008-7-28 在网上有很多关于在C#中使用NUnit的相关文章&#xff0c;但是我安装了NUnit后却不知道在C# Express中应该如何配置&#xff0c;相信很多人也遇到了同样的问题。根据自己的摸索总结了一下&#xff0c;希望对大…

如何利用离散Hopfield神经网络进行数字识别(2)

如何利用离散Hopfield神经网络进行数字识别

SQL语句实现取消自增列属性

由于在SQL-SERVER中&#xff0c;自增列属性不能直接修改&#xff0c;但可以通过以下方式变向实现 1、如果仅仅是指定值插入&#xff0c;可用以下语句&#xff0c;临时取消 SET IDENTITY_INSERT TableName ONINSERT INTO tableName(xx,xx) values(xx,xx)SET IDENTITY_INSERT Tab…

Mac OS 提高工作效率的几个快捷键

Mac OS X 命令行中组快捷键 几组导航快捷键 跳至行首 – ControlA 跳至行尾 – ControlE 跳至上一个单词 – Control<- 跳至下一个单词 – Control-> 跳至下一行 – ControlN 跳至上一行 – ControlP 删除上一个单词 – ControlW 删除当前光标位置到行首的文字 – Cont…