1. 程式人生 > >9、前置、後置、環繞通知

9、前置、後置、環繞通知

前置通知

使用@Before

第一種方法:先定義pointcut

@Pointcut("execution(* com..*.sleep(..))")
public void callSleep(){}

@Before(value="callSleep()")
public void beforeSleep(JoinPoint joinPoint){
    System.out.println("before sleep");
}

第二種方法將pointcut寫在@Before

@Before("within(com.codestd.springstudy.aop.People)"
) public void beforeSleep(JoinPoint joinPoint){ System.out.println("before sleep"); } @Before("execution(* com..*.sleep(..))") public void beforeSleep(JoinPoint joinPoint){ System.out.println("before sleep"); }

後置通知

@After(value = "callSleep()")
public void afterSleep(){
    System.out.println("after sleep"
); } --- @After("execution(* com..*.sleep(..))") public void beforeSleep(JoinPoint joinPoint){ System.out.println("before sleep"); }

獲取目標物件

在前置通知和後置通知中可以將JoinPoint作為方法的引數傳入通知方法(如上)。

joinPoint.getTarget()   //獲取目標物件
joinPoint.getArgs()     //獲取連線點方法執行時的入參列表
joinPoint.getSignature()    //獲取連線點的方法簽名物件
joinPoint.getThis() //獲取代理物件本身

環繞通知

通知優先順序如下環繞通知-->前置通知-->後置通知-->環繞通知

//@Around("execution(* com..*.sleep(..))")
@Around(value = "callSleep()")
public Object afterSleep(ProceedingJoinPoint joinPoint) throws Throwable{
    // start stopwatch
    Object retVal = joinPoint.proceed();
    // stop stopwatch
    return retVal;
}

在環繞通知中使用ProceedingJoinPoint獲取連線點資訊,需要在環繞通知呼叫連線點的proceed()方法手動執行方法,並且將方法的返回值作為通知方法的返回值返回。

ProceedingJoinPoint繼承JoinPoint子介面,它新增了兩個用於執行連線點方法的方法:
- java.lang.Object proceed() throws java.lang.Throwable:通過反射執行目標物件的連線點處的方法;
- java.lang.Object proceed(java.lang.Object[] args) throws java.lang.Throwable:通過反射執行目標物件連線點處的方法,不過使用新的入參替換原來的入參。