本篇文章小编给大家分享一下使用spring aop统一处理异常和打印日志方式代码示例,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看。
我们很容易写出带有很多try catch 和 logger.warn(),logger.error()的代码,这样一个方法本来的业务逻辑只有5行,有了这些,代码就变成了10行或者更多行,如:
public ResultDTOqueryUserByCardId(String cardId) { ResultDTO result = new ResultDTO (); 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 ResultDTOqueryUserByCardId(String cardId) { ResultDTO result = new ResultDTO (); 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配置文件中配置切面
这样,我们就可以统一处理异常和日志了。