2013-04-03 77 views
13

任何人都可以告诉我JoinpointProceedingjoinpoint有何区别?使用aspectJ在AOP中的Joinpoint VS ProceedingJoinPoint?

何时使用JoinpointProceedingjoinpoint在方面类的方法?

我曾经在我的JoinPointAspectJ class

@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(); 
    } 
} 

这里什么ProceedingJoinPoint会做特别的比较“JointPoint`?

还什么pjp.proceed()能为我们做什么?

回答

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

+0

Thans您的回复。所以你说的'pjp.proceed()'将调用两次'addBook()'方法? –

+0

不,首先会调用aroundAdvice方法,然后调用addBook()。 –

+0

你可以通过调试来看到它。 –

19

其中环绕是什么时候,如果执行的方法(或其它连接点),可以控制一种特殊的建议。这仅适用于各地的通知,因此它们需要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建议的另一特色是,他们必须有一个返回值,而其它的通知类型不能有一个。

+0

感谢您的黄金答复...还有一个疑问。 '如何使用ProceedingJoinPoint使用@Around获取方法的输入参数和返回值?' –

+0

参见上面的代码:输入参数可以通过'pjp.getArgs()'检索,方法通过'pjp.proceed()'返回值为' –

+0

+1。谢谢,明白了。 –