AOP的具體實踐-簡化結果返回的處理


原因:

  以前學習Spring的時候着重學習過AOP概念,但是一直也沒有用上,唯一碰到過的就是Spring內置的事務管理。現在碰到過一些結果后面的操作適合用到,所以這里就拿出來用一下,並且復習一下落下的知識。

概念:

  基本概念這個博主解釋的比較清楚,如果有不懂的可以去看一下。https://blog.csdn.net/csh624366188/article/details/7651702

  在我的認識里,如果某些方法重復性特別高,可以抽象出來形成一個切面,則可以使用AOP來簡化代碼,即在方法的某些部分動態的添加某些方法,起到簡化代碼的作用。

具體需求:

  項目的Service層通過webService獲取到數據,需要對獲取到的數據進行判斷處理,對其異常信息作出記錄和拋出異常。同時還需要在進入和結束方法的時候進行日志記錄。

知識點:

  配置方法:

  在這里使用的是注解的方式來配置的AOP,首先,要保證項目中除了Spring基本包以外還包含aopalliance-1.0.jar,aspectjrt-1.8.7.jar,aspectjweaver-1.8.7.jar,cglib-nodep-3.2.4.jar這四個jar包,這里將其打包放到百度雲,如果有需要的可以去下載。鏈接:https://pan.baidu.com/s/1rDqLY1lnWdiahVkLcZd_bw 密碼:0uea

  Spring配置添加如下, 添加<aop:aspectj-autoproxy />需要添加Spring的頭部內容

  注意aop不能添加到static方法上面。

    <aop:aspectj-autoproxy />  // 掃描AOP
    <!-- 這里配置后就不用再使用bean標簽配置bean了 -->
    <context:annotation-config></context:annotation-config>
    <!-- 去哪個包掃描生成bean -->
    <context:component-scan base-package="com.dazhong.jnfy.alipay.action" />

 

  首選建立切面類:其中的afterReturning就是主要的切面方法,用於對返回值進行判斷並且進行對應的操作,這樣可以不用再每個方法中都寫一次。

  
  @Pointcut("execution(* com.dazhong.jnfy.alipay.service.impl.*.*(..))"):表示AOP會代理那些方法,這里則表示com.dazhong.jnfy.alipay.service.impl包下面所有方法都會執行
  @After("picter()"):后置通知
  @Before("picter()"):前置通知
 
package com.dazhong.jnfy.alipay.aop;

import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; 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.json.JSONObject; import org.springframework.stereotype.Component; import com.dazhong.jnfy.alipay.exception.ConnectionException; import com.dazhong.jnfy.alipay.exception.ResultErrorException; import com.dazhong.utils.LogUtil;  @Component @Aspect public class ServiceAop { @Pointcut("execution(* com.dazhong.jnfy.alipay.service.impl.*.*(..))") public void picter() { } /** * @Description: 對返回值進行處理 * @param point * @param rvt * @throws ResultErrorException */ @AfterReturning(returning = "rvt", pointcut = "execution(* com.dazhong.jnfy.alipay.service.impl.*.*(..))") public void afterReturning(JoinPoint point, Object rvt) throws Exception { // Object rvt則是方法返回值,這里變量名稱要和注解retruning值相同 String[] strs = point.getSignature().getDeclaringTypeName().split("\\."); String fullname = strs[strs.length - 1] + "." + point.getSignature().getName(); JSONObject root = (JSONObject) rvt; if (rvt == null) { throw new ConnectionException("WebService連接失敗" + fullname); } else if (!root.has("resultCode") || !root.get("resultCode").toString().equals("0")) { // 返回數據異常 throw new ResultErrorException("WebService 返回結果異常:" + root.toString()); } } @Before("picter()") public void before(JoinPoint point) { String[] strs = point.getSignature().getDeclaringTypeName().split("\\."); String fullname = strs[strs.length - 1] + "." + point.getSignature().getName(); LogUtil.info("進入方法:" + fullname); } @After("picter()") public void after(JoinPoint point) { String[] strs = point.getSignature().getDeclaringTypeName().split("\\."); String fullname = strs[strs.length - 1] + "." + point.getSignature().getName(); LogUtil.info("方法結束:" + fullname); } }

  獲取參數/方法名:

    如果需要獲取目標方法的參數/名字,則需要在切面的方法中添加變量 JoinPoint point,通過這個對象來進行獲取。

     String allname = point.getSignature().getDeclaringTypeName();  // 獲取整個路徑 包名+類名
     System.out.println(allname);
     String[] split = allname.split("\\."); System.out.println("目標方法:" + split[split.length - 1] + "." + point.getSignature().getName()); // point.getSignature().getName() 獲取方法名 System.out.println("@Before:參數為:" + Arrays.toString(point.getArgs())); // 獲取目標方法的參數 point.getArgs()

 

 

  結果: 紅框內容就是AOP自動添加的。

  

  剩余代碼:

  目標方法:

  

    public JSONObject test() throws Exception{
        System.out.println("目標方法執行"); JSONObject js = new JSONObject(); js.put("resultCode", "-1"); return js; }

  測試方法:

  

    public static void main(String[] args) {
        ApplicationContext appCtx = new ClassPathXmlApplicationContext("applicationContext.xml"); ReserveServiceImpl b = (ReserveServiceImpl) appCtx.getBean("reserveServiceImpl"); JSONObject js = new JSONObject(); js.put("s", "111"); try { //JSONObject allDept = b.getDocterByTimeAndDept("YYKS002", "20180711");  b.test(); } catch (Exception e) { System.out.println(e); } }

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM