@Before 前置通知
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class BeforeExample {
@Before("execution(* com.xyz.myapp.dao.*.*(..))")
public void doAccessCheck() {
// ...
}
}
@AfterReturning 返回通知
当匹配的方法执行正常返回时运行.
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterReturning;
@Aspect
public class AfterReturningExample {
@AfterReturning("execution(* com.xyz.myapp.SystemArchitecture.dataAccessOperation())")
public void doAccessCheck() {
// ...
}
}
获取返回值
当我们想获取到某个方法的返回值时, 可以使用如下方式:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterReturning;
@Aspect
public class AfterReturningExample {
@AfterReturning(
pointcut="execution(* com.xyz.myapp.SystemArchitecture.dataAccessOperation())",
returning="retVal")
public void doAccessCheck(Object retVal) {
// ...
}
}
returning
表示返回值类型, 这里使用的是 Object
类型, 我们也可以设置指定类型 例如 List<String>
.
@AfterThrowing 异常通知
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterThrowing;
@Aspect
public class AfterThrowingExample {
@AfterThrowing(
pointcut="execution(* com.xyz.myapp.SystemArchitecture.dataAccessOperation())",
throwing="ex")
public void doRecoveryActions(DataAccessException ex) {
// ...
}
}
throwing
表示当抛出的是 DataAccessException
异常时, 才会调用此方法.
@After 后置通知
当匹配的方法执行完成后运行.
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.After;
@Aspect
public class AfterFinallyExample {
@After("execution(* com.xyz.myapp.SystemArchitecture.dataAccessOperation())")
public void doReleaseLock() {
// ...
}
}
@Around 围绕通知
在匹配的方法执行前后执行.
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class AroundExample {
@Around("execution(* com.example.demo.sss.TestService.*())")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("执行目标方法之前...");
Object retVal = pjp.proceed();
System.out.println("执行目标方法之后...");
return retVal + " ---> 1111";
}
}
该方法的第一个形参必须是 ProceedingJoinPoint
类型, 在方法体中调用 proceed
方法才会执行目标方法; 如果程序没有调用 proceed
方, 目标方法不会执行.
调用 proceed
方法时, 还可以传入一个 Object[]
对象, 该数组中的值将被传入目标方法作为实参. 如果传入的 Object[]
数组长度与目标方法所需要的参数个数不相等, 或者 Object[]
数组元素与目标方法所需参数的类型不匹配, 程序就会抛出异常.
获取通知参数
任何通知方法都可以声明一个类型为 org.aspectj.lang.JoinPoint
的参数, 作为它的第一个参数 JoinPoint
接口提供了许多有用的方法:
- getArgs(): 返回方法参数.
- getThis(): 返回代理对象.
- getTarget(): 返回目标对象.
- getSignature(): 返回建议的方法的描述.
- toString(): 打印建议方法的描述.