谁能告诉我
Joinpoint
和Proceedingjoinpoint
有什么区别吗?
什么时候在切面类的方法中使用
Joinpoint
和Proceedingjoinpoint
?
我在 AspectJ 类中使用了
JoinPoint
,例如:
@Pointcut("execution(* com.pointel.aop.test1.AopTest.beforeAspect(..))")
public void adviceChild(){}
@Before("adviceChild()")
public void beforeAdvicing(JoinPoint joinPoint /*,ProceedingJoinPoint pjp - used refer book marks of AOP*/){
//Used to get the parameters of the method !
Object[] arguments = joinPoint.getArgs();
for (Object object : arguments) {
System.out.println("List of parameters : " + object);
}
System.out.println("Method name : " + joinPoint.getSignature().getName());
log.info("beforeAdvicing...........****************...........");
log.info("Method name : " + joinPoint.getSignature().getName());
System.out.println("************************");
}
但是我在其他资源中看到的是:
@Around("execution(* com.mumz.test.spring.aop.BookShelf.addBook(..))")
public void aroundAddAdvice(ProceedingJoinPoint pjp){
Object[] arguments = pjp.getArgs();
for (Object object : arguments) {
System.out.println("Book being added is : " + object);
}
try {
pjp.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
}
与 'JointPoint
ProceedingJoinPoint
pjp.proceed()` 相比,? Also what will
会为我们做哪些不同的事情?
环绕通知是一种特殊的通知,可以控制何时以及是否执行方法(或其他连接点)。这仅适用于 around 建议,因此它们需要
ProceedingJoinPoint
类型的参数,而其他建议仅使用普通的 JoinPoint
。一个示例用例是缓存返回值:
private SomeCache cache;
@Around("some.signature.pattern.*(*)")
public Object cacheMethodReturn(ProceedingJoinPoint pjp){
Object cached = cache.get(pjp.getArgs());
if(cached != null) return cached; // method is never executed at all
else{
Object result = pjp.proceed();
cache.put(pjp.getArgs(), result);
return result;
}
}
在这段代码中(使用不存在的缓存技术来说明一点),只有当缓存没有返回结果时才会调用实际的方法。例如,这就是 Spring EHCache Annotations 项目的确切工作方式。
周围建议的另一个特点是它们必须有返回值,而其他建议类型不能有返回值。
@Around("execution(* com.mumz.test.spring.aop.BookShelf.addBook(..))")
这意味着在调用
com.mumz.test.spring.aop.BookShelf.addBook
方法之前,调用 aroundAddAdvice
方法。
后
System.out.println("Book being added is : " + object);
操作完成。它会调用你的实际方法addBook()
。 pjp.proceed()
将调用 addBook()
方法。
将 JoinPoint 与以下建议类型一起使用:
@Before, @After, @AfterReturning, @AfterThrowing
将 ProceedingJoinPoint 与以下建议类型一起使用:
@Around
ProceedingJoinPoint
是具有附加功能的 JoinPoint
。
ProceedingJoinPoint
与 @Around
建议一起使用。 @Around
是非常强大的建议,结合了其余建议的功能。
ProceedingJoinPoint::proceed
基本上是用来执行原方法的。
考虑以下示例:
@Around("@annotation(com.annotations.ExecutionLoggerAround)")
public void executeLogger(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("Method execution starts at :: " + System.currentTimeMillis());
proceedingJoinPoint.proceed();
System.out.println("Method execution completes at :: " + System.currentTimeMillis());
}
@ExecutionLoggerAround
public void generateReport() {
System.out.println("Generating XLS report !!");
}
public @interface ExecutionLogger {
}
现在当您调用
generateReport
时,Around
建议将被执行。如果跳过第 proceedingJoinPoint.proceed()
行,则不会执行实际方法。您将在控制台中仅看到这两个println
。
PS:为了更好地理解,你需要知道 AOP 是如何工作的。 Spring 使用 JDK 代理或 CGLIB 代理创建代理对象。所以它实际上是在运行时执行的代理对象,它在幕后使用我们的方法。
我已经写了更多关于此的内容这里