AOP中使用aspectJ的Joinpoint VS ProceedingJoinPoint?

问题描述 投票:0回答:4

谁能告诉我

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
会为我们做哪些不同的事情?

java spring aspectj spring-aop
4个回答
33
投票

环绕通知是一种特殊的通知,可以控制何时以及是否执行方法(或其他连接点)。这仅适用于 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 项目的确切工作方式。

周围建议的另一个特点是它们必须有返回值,而其他建议类型不能有返回值。


12
投票
@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()
方法。


3
投票

JoinPoint 与以下建议类型一起使用:

 @Before, @After, @AfterReturning, @AfterThrowing

ProceedingJoinPoint 与以下建议类型一起使用:

@Around

0
投票

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 代理创建代理对象。所以它实际上是在运行时执行的代理对象,它在幕后使用我们的方法。

我已经写了更多关于此的内容这里

© www.soinside.com 2019 - 2024. All rights reserved.