三、计算拦截器链
调用链图:
JdkDynamicAopProxy实现了InvocationHandler接口,当其创建的JDK Proxy上的某一个方法被调用时,将会被JdkDynamicAopProxy类中的invoke(..)方法拦截:
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
...
try {
...
target = targetSource.getTarget();
if (target != null) {
targetClass = target.getClass();
}
// 计算拦截器链
List chain = this.advised.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this.advised, proxy, method, targetClass);
if (chain.isEmpty()) {
// 拦截器链为空,直接调用目标对象上的方法
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
}
else {
// 调用方法
invocation = new ReflectiveMethodInvocation(
proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
}
...
return retVal;
}
finally {
...
}
}
...
}
AdvisedSupport中AdvisorChainFactory的默认实现是HashMapCachingAdvisorChainFactory,它能将某一方法上的拦截器链进行缓存。
public final class HashMapCachingAdvisorChainFactory implements AdvisorChainFactory {
public List getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Object proxy, Method method, Class targetClass) {
private final Map methodCache = CollectionFactory.createIdentityMapIfPossible(32);
List cached = (List) this.methodCache.get(method);
if (cached == null) {
// recalculate
cached = AdvisorChainFactoryUtils.calculateInterceptorsAndDynamicInterceptionAdvice(
config, proxy, method, targetClass);
this.methodCache.put(method, cached);
}
return cached;
}
...
}
工具类AdvisorChainFactoryUtils提供了计算拦截器的方法:
public abstract class AdvisorChainFactoryUtils {
public static List calculateInterceptorsAndDynamicInterceptionAdvice(
Advised config, Object proxy, Method method, Class targetClass) {
List interceptorList = new ArrayList(config.getAdvisors().length);
...
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
for (int i = 0; i < config.getAdvisors().length; i++) { //遍历每一个Advisor
Advisor advisor = config.getAdvisors()[i];
if (advisor instanceof PointcutAdvisor) {
// add it conditionally
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
// 计算该Advisor是否适合该class
if (pointcutAdvisor.getPointcut().getClassFilter().matches(targetClass)) {
// 将advisor持有的before、after、throws等advice转化为统一
// 的MethodInterceptor
Interceptor[] interceptors = registry.getInterceptors(advisor);
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
// 计算该Advisor是否适合该method
if (methodMatches(mm,method, targetClass,hasIntroductions)) {
if (mm.isRuntime()) {
... //动态interceptor
}
else {
// 将该Advisor加入method的interceptor列表
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
else if (advisor instanceof IntroductionAdvisor) {
...
}
}
return interceptorList;
}
...
}