Spring
AOP中,有Before advice和After advice,这两个advice从字面上就可以很容易理解,但是Around
advice就有点麻烦了。
乍一看好像是Before
advice和After
advice的组合,也就是说pointcut会在joinpoint执行前后各执行一次。但是这种理解是不正确的,如果这样理解的话,就会产生这样的疑问:spring aop
Around类型为什么只执行一次,这个帖子是我碰巧看到。
那么怎么样理解才是正确的呢?我们来看一下Spring官方是怎么解释Around
advice的:
Around advice
runs "around" a matched method execution. It has the opportunity to
do work both before and after the method executes, and to determine
when, how, and even if, the method actually gets to execute at all.
Around advice is often used if you need to share state before and
after a method execution in a thread-safe manner (starting and
stopping a timer for example).
大概的意思就是说,Around
advice可以通过一个在joinpoint执行前后做一些事情的机会,可以决定什么时候,怎么样去执行joinpoint,甚至可以决定是否真的执行joinpoint的方法调用。Around
advice通常是用在下面这样的情况:
在多线程环境下,在joinpoint方法调用前后的处理中需要共享一些数据。如果使用Before
advice和After
advice也可以达到目的,但是就需要在aspect里面创建一个存储共享信息的field,而且这种做法并不是线程安全的。
现在,明白Spring设计Around
advice的目的之后,我们来看下具体的用法。
import
org.aspectj.lang.annotation.Aspect;
import
org.aspectj.lang.annotation.Around;
import
org.aspectj.lang.ProceedingJoinPoint;
@Aspect
public class AroundExample
{
@Around("com.xyz.myapp.SystemArchitecture.businessService()")
public Object
doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable
{
// start stopwatch
相当于是before
advice
Object retVal = pjp.proceed();
// stop stopwatch 相当于是after
advice
return retVal;
}
}
现在大家看明白了吧,并不是在joinpoint执行前后各调用一次pointcut,而是在pointcut中把joinpoint给around起来。