Spring AOP 環繞通知
阿新 • • 發佈:2019-01-03
Spring AOP的環繞通知和前置、後置通知有著很大的區別,主要有兩個重要的區別:
1)目標方法的呼叫由環繞通知決定,即你可以決定是否呼叫目標方法,而前置和後置通知是不能決定的,它們只是在方法的呼叫前後執行通知而已,即目標方法肯定是要執行的。joinPoint.proceed()就是執行目標方法的程式碼。
2)環繞通知可以控制返回物件,即可以返回一個與目標物件完全不同的返回值。雖然這很危險,但是卻可以做到。
下面的例子使用環繞通知,完成日誌寫入。
1)Spring配置檔案加入AOP定義
2)通知處理類的定義<!--配置第三方平臺請求日誌切面--> <bean id="logHandler" class="com.test.LogHandler" /> <aop:config> <aop:aspect id="logAspect" ref="logHandler"> <aop:pointcut id="logPointCut" expression="execution(public * com.test.itf.*Ctr.*Hdl(..))"/> <aop:around method="doAround" pointcut-ref="logPointCut"/> </aop:aspect> </aop:config>
public class LogHandler { Logger logger = LoggerFactory.getLogger(LogHandler.class); @Resource(name="logService") private LogService logService; public Object doAround(ProceedingJoinPoint joinPoint){ try{ Object ret = joinPoint.proceed(); //執行目標方法 Object[] args =joinPoint.getArgs(); //獲取目標方法引數 String arg0 = joinPoint.getSignature().getDeclaringTypeName(); HttpServletRequest request =null ; for(int i=0;i<args.length;i++){ if(args[i] instanceof HttpServletRequest ){ request = (HttpServletRequest) args[i]; //獲取request引數物件 break; } } JdResponse resp = (JdResponse) ret; //目標方法執行返回的物件
ConsumerLog log = new ConsumerLog(); log.setId(UuidUtil.get32UUID()); log.setCreateDate(new Date()); log.setAppId(request.getParameter("appId")); log.setNonceStr(request.getParameter("nonceStr")); log.setOutput(JSONObject.toJSONString(resp)); log.setInput(getHttpParameters(request)); logService.insertLog(log); //寫入日誌表 return resp; }catch(Throwable e){ logger.error("error in logService doArround:",e); return new JdResponse(JdResponse.CODE.serverError,"系統錯誤",null); } }