在前面的章节中,谈到代理对象的创建:参考Spring注解--AOP原理(四):业务bean与代理bean的创建, 接下来谈谈代理对象的执行。
1. 执行目标方法
- 调用代理对象的intercept方法
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
//获取拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
//如果拦截器为空,则直接调用业务bean的方法,否则invoke代理bean的方法
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}else {
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
- 获取拦截器链:将List<Advisor>封装成为 List<MethodInterceptor>
@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, Class<?> targetClass) {
List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
for (Advisor advisor : config.getAdvisors()) {
...
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
...
interceptorList.addAll(Arrays.asList(interceptors));
}
return interceptorList;
}
- 如果没有拦截器,直接运行目标方法:
retVal = methodProxy.invoke(target, argsToUse)
- 如果有拦截器,传入拦截器链,并触发CglibMethodInvocation 中的proceed方法
@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();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
...
//逐一触发拦截器链里的每一个拦截器。触发的顺序很重要,这里的代码写的很有意思,很有借鉴意义。
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
网友评论