spring aop中使用@Pointcut註解抽取可重用的切入點表達式

針對同一個切入點,如果有多個通知方法將切入時,通常我們需要標註多個註解,每個註解需要使用切入點表達式,告訴spring,當前通知方法在何時執行。當一個切入點需要更改時,就需要同時更改多個。爲了避免這種麻煩,提高切入點表達式的可重用性,以此衍生出的@Pointcut,可以用於標誌一個切入點。

示例:
如前文中的切面類StudentServiceLogger ,針對StudentServiceImpl類的所有方法都切入了四個通知,如果某天,我想改成只對其中一個方法切入時,就需要來修改這四個註解的切入點表達式。

@Aspect
@Component
public class StudentServiceLogger {

    @Before("execution(* com.wuwl.service.impl.StudentServiceImpl.*(..) )")
    public void doBefore(JoinPoint joinPoint){
        Object[] args = joinPoint.getArgs();
        String methodName = joinPoint.getSignature().getName();
        System.out.println(methodName+"方法執行前...");
        System.out.println("參數爲:"+ Arrays.asList(args));
    }

    @After("execution(* com.wuwl.service.impl.StudentServiceImpl.*(..) )")
    public void doAfter(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        System.out.println(methodName+"方法執行後...");
    }

    @AfterReturning(value = "execution(* com.wuwl.service.impl.StudentServiceImpl.*(..) )" , returning = "returning")
    public void doReturn(JoinPoint joinPoint,Object returning){
        String methodName = joinPoint.getSignature().getName();
        System.out.println(methodName+"方法返回,返回值爲:"+returning);

    }

    @AfterThrowing(value = "execution(* com.wuwl.service.impl.StudentServiceImpl.*(..) )",throwing = "ex")
    public void doThrow(JoinPoint joinPoint,Exception ex){
        String methodName = joinPoint.getSignature().getName();
        System.out.println(methodName+"方法異常,異常信息爲:"+ex.getMessage());
    }

}

使用@Pointcut的示例
上面的示例,完全等價於下面這個切面類。

@Aspect
@Component
public class StudentServiceLogger {

    @Pointcut("execution(* com.wuwl.service.impl.StudentServiceImpl.*(..) )")
    public void basePointCut(){}
    
    @Before("basePointCut()")
    public void doBefore(JoinPoint joinPoint){
        Object[] args = joinPoint.getArgs();
        String methodName = joinPoint.getSignature().getName();
        System.out.println(methodName+"方法執行前...");
        System.out.println("參數爲:"+ Arrays.asList(args));
    }

    @After("basePointCut()")
    public void doAfter(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        System.out.println(methodName+"方法執行後...");
    }

    @AfterReturning(value = "basePointCut()" , returning = "returning")
    public void doReturn(JoinPoint joinPoint,Object returning){
        String methodName = joinPoint.getSignature().getName();
        System.out.println(methodName+"方法返回,返回值爲:"+returning);

    }

    @AfterThrowing(value = "basePointCut()",throwing = "ex")
    public void doThrow(JoinPoint joinPoint,Exception ex){
        String methodName = joinPoint.getSignature().getName();
        System.out.println(methodName+"方法異常,異常信息爲:"+ex.getMessage());
    }

}

我們聲明瞭一個basePointCut()空方法,並且返回值需要爲void,爲該方法標註上@Pointcut註解,鍵入之前我們那四個通知方法的公用切入點表達式。然後,將後續的所有使用到之前那個切入表達式的地方,替換成basePointCut()這個方法名,以此指向同一個的切入點表達式。後續的所有變動,我都可以只更改basePointCut()方法上的切入表達式即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章