iT邦幫忙

2022 iThome 鐵人賽

DAY 17
0

Review

AOP是在處理Cross-cutting concerns,將某段代碼(日誌)動態切入(不把日誌程式hardcode到業務邏輯方法中)到指定方法(加減乘除)的指定位置進行運行。
昨天我們學到了AOP中Advice的執行順序、透過Advice方法給定參數JointPoint可以取得方法的相關訊息,在AfterReturning、AfterThrowing可在方法給定參數與在pointcut expression來接收回傳值與Exception

今日我們將探討AOP的Around advice與如何共用pointcut expression

重用pointcut expression

  1. 宣告一個空方法
  2. 方法標註@Pointcut
  3. 其他Advice expression輸入該空方法
@Aspect
@Component
public class LogUtils {
    @Pointcut(value = "execution(public int com.swj.MyCalculator.*(..))")
    public void pointCutExpressionShare(){}
    
    @Before("pointCutExpressionShare()")
    public static void logStart(JoinPoint jointPoint){
        //取得方法名稱,與parameter
        System.out.println("["+jointPoint.getSignature().getName()+"] method start,parameter:"+Arrays.asList(jointPoint.getArgs()));
    }

    @AfterReturning(value = "pointCutExpressionShare()",returning = "result")
    public static void logReturn(JoinPoint joinPoint, Object result){
        System.out.println("["+joinPoint.getSignature().getName()+"] method completed,result is "+result);
    }

    @After("pointCutExpressionShare()")
    public static void logEnd(JoinPoint joinPoint){
        System.out.println("["+joinPoint.getSignature().getName()+"] method end");
    }

    @AfterThrowing(value = "pointCutExpressionShare()",throwing = "exception")
    public static void logException(JoinPoint joinPoint,Exception exception){
        System.out.println("["+joinPoint.getSignature().getName()+"] method throws exception:"+exception);
    }

}

Result
https://ithelp.ithome.com.tw/upload/images/20221006/2012808459TCHm39Ut.jpg

Around Advice

自定義的Advice方法,包含前面4種的Advice

  • 方法參數為ProceedingJoint
  • 需要Return Object讓其他通知方法可以繼續運作
@Aspect
@Component
public class LogUtils {
@Around("pointCutExpressionShare()")
    public Object aroundAdvice(ProceedingJoinPoint pjp){
        Object[] params = pjp.getArgs();
        String methodName = pjp.getSignature().getName();
        Object proceed =null;
        try {
            System.out.println("["+methodName+"][Around Advice] Before");
            //目標方法invoke
            proceed = pjp.proceed(params);
            System.out.println("["+methodName+"][Around Advice] AfterReturning");
        }catch (Throwable e){
            System.out.println("["+methodName+"][Around Advice] AfterThrowing");
        }finally {
            System.out.println("["+methodName+"][Around Advice] After");
        }

        return proceed;
    }
}

Result
https://ithelp.ithome.com.tw/upload/images/20221006/20128084sUR0pkK1ld.jpg

Around Advice執行順序

Around_Before -> @Before -> target invoke -> Around_Returning/Around_Throwing -> Around_After -> @After -> AfterReturning/AfterThrowing

 @AfterThrowing(value = "pointCutExpressionShare()",throwing = "exception")
    public static void logException(JoinPoint joinPoint,Exception exception){
        System.out.println("["+joinPoint.getSignature().getName()+"] method throws exception:"+exception);
    }

@Around("pointCutExpressionShare()")
public Object aroundAdvice(ProceedingJoinPoint pjp){
    Object[] params = pjp.getArgs();
    String methodName = pjp.getSignature().getName();
    Object proceed =null;
    try {
        //@Before
        System.out.println("["+methodName+"][Around Advice] Before");
        //目標方法invoke
        proceed = pjp.proceed(params);
        //AfterReturning
        System.out.println("["+methodName+"][Around Advice] AfterReturning");
    }catch (Throwable e){
        //AfterThrowing
        System.out.println("["+methodName+"][Around Advice] AfterThrowing");
        throw new RuntimeException(e);
    }finally {
        //After
        System.out.println("["+methodName+"][Around Advice] After");
    }
    return proceed;
}

Result
https://ithelp.ithome.com.tw/upload/images/20221006/20128084PBPyfnMCho.jpg


上一篇
Day20 - AOP (2) Advice
下一篇
Day22 - AOP (4) 多Aspect的Advice運行順序 與 XML設定AOP
系列文
這些年,我們早該學會的Spring Framework30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言