国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Spring MVC AOP通過注解方式攔截Controller等實現日志管理

2019-11-11 02:25:52
字體:
來源:轉載
供稿:網友

問題介紹

       最近在做微信企業號的Saas套件開發,因而前端頁面都是使用H5做的。為了提高開發效率,使得前后端基本能夠并行開發,我們后端開發人員和前端開發人員就約定使用前后端分離的開發方式。

  

      一旦采用前后端分離的開發方式,我們后端人員就只提供接口了。因為我們是采用sPRing + springmvc_mybatis的通用架構。所以這種純接口的開發非常方便。

 

      但是在開發調試過程中遇到一個痛點就是在測試環境中一旦遇到錯誤比較難定位問題,因為微信中的調試器打開比較麻煩,所以要看一個問題需要耗費比較長的時間(相信使用微信工具調試的人深知此事)。所以一般情況下,后端開發人員都在日志中打印前端傳給后端的請求參數以及返回給前端的結果。因而代碼中充斥著這樣的邏輯。

     

	/**	 * xxxx	 * 	 * @param queryVo	 * @return	 */	@RequestMapping(value = "/xxxx")	@ResponseBody	public Map<String, Object> xxxx(OrderStatisticsQueryParams queryParams)	{		logger.debug("請求參數:" + JsonUtil.toJSONString(queryParams));		// PROCESS result		return result;	}

  

      如果只是一個兩個接口也就罷了,但是之后我們打算都采用前后端分離的方式來開發,因而代碼中必定到處都充斥著這樣的重復邏輯。

  

      因為我想到了可以使用AOP來解決這個問題。

      

問題解決方案

       1.使用自定義注解來標識哪些接口需要打印參數日志,而不是一刀切,所有的接口都需要打印日志

     2.考慮線上的情況。一般來講打印日志的需求只會在開發測試階段才會有,而正常情況下線上不需要打印請求參數。而且打印參數也會浪費線上的資源。

 

     二話不說,先上自定義日志注解的代碼

    

@Retention(RetentionPolicy.RUNTIME)@Target({	ElementType.METHOD})public @interface SystemLog{	String description() default "";  // 方法描述}

       再上切面的代碼

package com.zk.platform.aop;import java.lang.reflect.Method;import java.util.Map;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;import org.aspectj.lang.reflect.MethodSignature;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Component;import com.alibaba.fastjson.JSON;import com.google.common.collect.Maps;import com.zk.platform.annotation.SystemLog;import com.zk.platform.util.PropertiesUtil;@Aspect@Componentpublic class SystemLogAop{	private static final boolean ENABLE_METHOD_LOGGING = "true".equals(PropertiesUtil.getSysProp("method.args.logging",			"false"));	private static final Logger logger = LoggerFactory.getLogger(SystemLogAop.class);	@Pointcut("@annotation(com.zk.platform.annotation.SystemLog)")	public void systemLogPointCut()	{	}	@Before("systemLogPointCut()")	public void beforeExec(JoinPoint joinPoint)	{		// 不開啟的話則不打印日志		if (!ENABLE_METHOD_LOGGING)		{			return;		}		try		{			String targetName = joinPoint.getTarget().getClass().getSimpleName();			String methodName = joinPoint.getSignature().getName();			MethodSignature ms = (MethodSignature) joinPoint.getSignature();			Object[] arguments = joinPoint.getArgs();			String[] parameterNames = ms.getParameterNames();			Method method = ms.getMethod();			SystemLog systemLog = method.getAnnotation(SystemLog.class);			if (arguments != null && parameterNames != null && arguments.length == parameterNames.length					&& arguments.length > 0)			{				Object argObj = null;				if (arguments.length == 1)				{					argObj = arguments[0];				}				else				{					Map<String, Object> map = Maps.newHashMapWithExpectedSize(arguments.length);					for (int i = 0; i < arguments.length; i++)					{						map.put(parameterNames[i], arguments[i]);					}					argObj = map;				}				logger.debug("{}.{}({}) args are:{}", targetName, methodName, systemLog.description(),						JSON.toJSONString(argObj));			}			else			{				logger.debug("{}.{}({}) invoked and no args", targetName, methodName, systemLog.description());			}		}		catch (Exception e)		{			logger.warn("打印日志異常:{}", e);		}	}	@AfterReturning(pointcut = "systemLogPointCut()", returning = "result")	public void afterReturning(JoinPoint joinPoint, Object result)	{		// 不開啟的話則不打印日志		if (!ENABLE_METHOD_LOGGING)		{			return;		}		try		{			String targetName = joinPoint.getTarget().getClass().getSimpleName();			String methodName = joinPoint.getSignature().getName();			MethodSignature ms = (MethodSignature) joinPoint.getSignature();			Method method = ms.getMethod();			SystemLog systemLog = method.getAnnotation(SystemLog.class);			logger.debug("{}.{}({}) return value is:{}", targetName, methodName, systemLog.description(),					JSON.toJSONString(result));		}		catch (Exception e)		{			logger.warn("打印日志異常:{}", e);		}	}} 

      注意,日志功能是否生效由參數"method.args.logging來控制,保證線上不受影響。

       

問題解決過程中遇到的問題

     配置后,發現切面沒有生效。

    解決方案如下  

    <!-- 最重要:::如果放在spring-context.xml中,這里的aop設置將不會生效 -->    <aop:aspectj-autoproxy proxy-target-class="true"/>   

   在spring配置文件中加上這句

    <aop:aspectj-autoproxy proxy-target-class="true"/>

     

 

  

   

    

 

  

    


上一篇:引用傳遞圖解

下一篇:IoBuffer

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 阿拉善右旗| 娄底市| 来宾市| 开平市| 时尚| 乌兰县| 米易县| 长葛市| 永昌县| 双鸭山市| 长乐市| 定远县| 闵行区| 平顶山市| 揭阳市| 文登市| 安国市| 阳信县| 河津市| 昌宁县| 四川省| 论坛| 滦南县| 余干县| 巴青县| 花莲市| 安达市| 东莞市| 剑阁县| 大新县| 岑巩县| 玛沁县| 册亨县| 琼海市| 太谷县| 美姑县| 西乌珠穆沁旗| 图木舒克市| 贵州省| 张家口市| 西乌|