浅析AOP源码(二)

转载自:https://blog.csdn.net/luanlouis/article/details/51155821

  

1、Spring内部创建代理对象的过程

  在Spring的底层,如果配置了AOP,Spring会为每一个Bean创建一个对应的ProxyFactoryBean的FactoryBean来创建某个对象的代理对象。
  假定有一个接口TicketService及其实现类RailwayStation,打算创建一个代理类,在执行TicketService的方法时的各个阶段,插入对应的业务代码。

1
2
3
4
5
6
7
8
9
10
public interface TicketService {
//售票
public void sellTicket();

//问询
public void inquire();

//退票
public void withdraw();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
public class RailwayStation  implements TicketService {
public void sellTicket(){
System.out.println("售票............");
}

public void inquire() {
System.out.println("问询.............");
}

public void withdraw() {
System.out.println("退票.............");
}
}
1
2
3
4
5
6
public class TicketServiceBeforeAdvice implements MethodBeforeAdvice {

public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("BEFORE_ADVICE: 欢迎光临代售点....");
}
}
1
2
3
4
5
6
public class TicketServiceAfterReturningAdvice  implements AfterReturningAdvice {
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("AFTER_RETURNING:本次服务已结束....");
}
}
1
2
3
4
5
6
7
8
9
public class TicketServiceAroundAdvice  implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("AROUND_ADVICE:BEGIN....");
Object returnValue = invocation.proceed();
System.out.println("AROUND_ADVICE:END.....");
return returnValue;
}
}
1
2
3
4
5
6
7
8
9
10
11
public class TicketServiceThrowsAdvice implements ThrowsAdvice {

public void afterThrowing(Exception ex) {
System.out.println("AFTER_THROWING....");
}

public void afterThrowing(Method method, Object[] args, Object target, Exception ex) {
System.out.println("调用过程出错啦!!!!!");
}

}

  然后来手动使用ProxyFactoryBean来创建Proxy对象,并将相应的几种不同的Advice加入这个proxy对应的各个执行阶段中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public static void main(String[] args) {
Advice beforeAdvice = new TicketServiceBeforeAdvice();
Advice afterReturningAdvice = new TicketServiceAfterReturningAdvice();
Advice aroundAdvice = new TicketServiceAroundAdvice();
Advice throwsAdvice = new TicketServiceThrowsAdvice();

RailwayStation railwayStation = new RailwayStation();

// 创建ProxyFactoryBean,用以创建指定对象的Proxy对象
ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
// 设置Proxy的接口
proxyFactoryBean.setInterfaces(TicketService.class);
// 设置RealSubject
proxyFactoryBean.setTarget(railwayStation);
// 使用JDK基于接口实现机制的动态代理生成Proxy代理对象,如果想使用CGLIB,需要将这个flag设置成true
proxyFactoryBean.setProxyTargetClass(false);

// 添加不同的Advice
proxyFactoryBean.addAdvice(afterReturningAdvice);
proxyFactoryBean.addAdvice(aroundAdvice);
proxyFactoryBean.addAdvice(throwsAdvice);
proxyFactoryBean.addAdvice(beforeAdvice);

// 通过ProxyFactoryBean生成Proxy对象
TicketService ticketService = (TicketService) proxyFactoryBean.getObject();
ticketService.sellTicket();
}

  运行结果:

1
2
3
4
5
AROUND_ADVICE:BEGIN....
BEFORE_ADVICE: 欢迎光临代售点....
售票............
AROUND_ADVICE:END.....
AFTER_RETURNING:本次服务已结束....

  我们成功地创建了一个通过一个ProxyFactoryBean和真实的实例对象创建出了对应的代理对象,并将各个Advice加入到proxy代理对象中。

  

2、Spring AOP的核心ProxyFactoryBean

  上面通过了使用ProxyFactoryBean实现了AOP的功能,在使用时通过addAdvice(Advice advice)把各类Advice添加到ProxyFactoryBean(实际是父类AdvisedSupport)中:

1
2
3
4
public void addAdvice(Advice advice) throws AopConfigException {
int pos = this.advisors.size();
addAdvice(pos, advice);
}

  AdvisedSupport中维护了private List<Advisor> advisors = new LinkedList<Advisor>();列表,addAdvice中会把advice包装为DefaultPointcutAdvisor加入到这个列表里。
  也就是说ProxyFactoryBean知道Advice信息,可以根据特定的类名和方法名返回对应的AdviceChain,用以表示需要执行的Advice串。当使用proxy时,对proxy对象调用的方法,都最终被转到这个类的invoke()方法中。以JdkDynamicAopProxy为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
//...略
/** Proxy的配置信息,这里主要提供Advisor列表,并用于返回AdviceChain */
private final AdvisedSupport advised;

//...略
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;

TargetSource targetSource = this.advised.targetSource;
Class<?> targetClass = null;
Object target = null;

try {
//...略
Object retVal;

//...略
// 获取当前调用方法的拦截链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

// 如果没有拦截链,则直接调用Joinpoint连接点的方法。
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// 根据给定的拦截链和方法调用信息,创建新的MethodInvocation对象,
// 整个拦截链的工作逻辑都在这个ReflectiveMethodInvocation里
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
}

//...略
return retVal;
}
finally {
//...略
}
}
}

  来看关键的getInterceptorsAndDynamicInterceptionAdvice函数:

1
2
3
4
5
6
7
8
9
10
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
MethodCacheKey cacheKey = new MethodCacheKey(method);
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null) {
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
this.methodCache.put(cacheKey, cached);
}
return cached;
}

  最终是调用到了DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, Class<?> targetClass) {

// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list.
List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();

for (Advisor advisor : config.getAdvisors()) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
else if (advisor instanceof IntroductionAdvisor) {
//...略
}
else {
//...略
}
}

return interceptorList;
}

  代码比较长,主要看for循环的第一个if分支。config.getAdvisors()返回的就是之前通过addAdvisor添加的Advisor列表(new DefaultPointcutAdvisor(advice))。registry.getInterceptors(advisor)是把advisor转换成MethodInterceptor[]:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
Advice advice = advisor.getAdvice();
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
}

  AdvisorAdapter的实例有AfterReturningAdviceAdapter、MethodBeforeAdviceAdapter、ThrowsAdviceAdapter分别用于转换AfterReturningAdvice、MethodBeforeAdvice、ThrowsAdvice为AfterReturningAdviceInterceptor、MethodBeforeAdviceInterceptor、ThrowsAdviceInterceptor。注意,示例代码里的TicketServiceAroundAdvice类是MethodInterceptor的子类,不需要AdvisorAdapter转换。

  这里创建MethodInterceptor链,然后构造ReflectiveMethodInvocation实例,调用proceed()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@Override
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}

// 取得第拦截器链上第N个拦截器
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}

  初始时,this.currentInterceptorIndex=-1this.interceptorsAndDynamicMethodMatchers即先前创建的MethodInterceptor[]。
  第一步,取MethodInterceptor[]中的第0个,即AfterReturningAdviceInterceptor:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {

private final AfterReturningAdvice advice;

public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}

@Override
public Object invoke(MethodInvocation mi) throws Throwable {
Object retVal = mi.proceed();
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
}

  先执行mi.proceed(),即ReflectiveMethodInvocation实例的proceed()方法,进入proceed()后,取MethodInterceptor[]中的第1个,即TicketServiceAroundAdvice:

1
2
3
4
5
6
7
8
9
public class TicketServiceAroundAdvice implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("AROUND_ADVICE:BEGIN....");
Object returnValue = invocation.proceed();
System.out.println("AROUND_ADVICE:END.....");
return returnValue;
}
}

  同理再次进入proceed()后,取MethodInterceptor[]中的第2个,即ThrowsAdviceInterceptor:

1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
catch (Throwable ex) {
Method handlerMethod = getExceptionHandler(ex);
if (handlerMethod != null) {
invokeHandlerMethod(mi, ex, handlerMethod);
}
throw ex;
}
}

  之后进入proceed()后,取MethodInterceptor[]中的第3个,MethodBeforeAdviceInterceptor:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {

private MethodBeforeAdvice advice;

public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}

@Override
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
return mi.proceed();
}

}

  之后进入proceed(),this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1满足条件,进入invokeJoinpoint:

1
2
3
protected Object invokeJoinpoint() throws Throwable {
return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}

  这里执行被代理对象的方法调用。然后根据方法栈的调用依次执行完MethodBeforeAdviceInterceptor->ThrowsAdviceInterceptor->TicketServiceAroundAdvice->AfterReturningAdviceInterceptor。所以最终的运行情况是:

1
2
3
4
5
AROUND_ADVICE:BEGIN....
BEFORE_ADVICE: 欢迎光临代售点....
售票............
AROUND_ADVICE:END.....
AFTER_RETURNING:本次服务已结束....