Spring AOP深入理解之拦截器调用
Spring AOP代理对象生成回顾
既然代理对象已经生成,那么拦截器是如何被调用的呢
@Override
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
classloader类加载器,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
proxiedInterfaces,一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口
this,表示JdkDynamicAopProxy自身,因为JdkDynamicAopProxy实现了InvocationHandler接口
@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 {
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
//目标对象未实现equals方法
return equals(args[0]);
}
if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
//目标对象未实现hashcode方法
return hashCode();
}
if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
//这里就是目标对象方法的调用
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
if (this.advised.exposeProxy) {
// 获得当前的对象
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
//目标对象可能源自一个池或者一个简单的方法
target = targetSource.getTarget();
if (target != null) {
targetClass = target.getClass();
}
// 得到拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// 检查是否定义了拦截器方法,如果没有的话直接调用目标方法
if (chain.isEmpty()) {
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
}
else {
//我们需要创建一个调用方法
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// proceed内部实现了递归调用遍历拦截器链
retVal = invocation.proceed();
}
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
retVal = proxy;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method); } return retVal; } finally { if (target != null && !targetSource.isStatic()) { // 释放target对象 targetSource.releaseTarget(target); } if (setProxyContext) { // 替换回原来的proxy AopContext.setCurrentProxy(oldProxy); } } }
上面的invoke()主要分为三部分
首先看拦截器链是如获得的。
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;
}
/**
* 从提供的配置实例config中获取advisor列表,遍历处理这些advisor.如果是IntroductionAdvisor,
* 则判断此Advisor能否应用到目标类targetClass上.如果是PointcutAdvisor,则判断
* 此Advisor能否应用到目标方法method上.将满足条件的Advisor通过AdvisorAdaptor转化成Interceptor列表返回.
*/
public List getInterceptorsAndDynamicInterceptionAdvice(Advised config, Methodmethod, Class targetClass) {
List interceptorList = new ArrayList(config.getAdvisors().length);
//查看是否包含IntroductionAdvisor
boolean hasIntroductions = hasMatchingIntroductions(config,targetClass);
//这里实际上注册一系列AdvisorAdapter,用于将Advisor转化成MethodInterceptor
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
Advisor[] advisors = config.getAdvisors();
for (int i = 0; i <advisors.length; i++) {
Advisor advisor = advisors[i];
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor= (PointcutAdvisor) advisor;
if(config.isPreFiltered() ||pointcutAdvisor.getPointcut().getClassFilter().matches(targetClass)) {
//TODO: 这个地方这两个方法的位置可以互换下
//将Advisor转化成Interceptor
MethodInterceptor[]interceptors = registry.getInterceptors(advisor);
//检查当前advisor的pointcut是否可以匹配当前方法
MethodMatcher mm =pointcutAdvisor.getPointcut().getMethodMatcher();
if (MethodMatchers.matches(mm,method, targetClass, hasIntroductions)) {
if(mm.isRuntime()) {
// Creating a newobject instance in the getInterceptors() method
// isn't a problemas we normally cache created chains.
for (intj = 0; j < interceptors.length; j++) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptors[j],mm));
}
} else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
} else if (advisor instanceof IntroductionAdvisor){
IntroductionAdvisor ia =(IntroductionAdvisor) advisor;
if(config.isPreFiltered() || ia.getClassFilter().matches(targetClass)) {
Interceptor[] interceptors= registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
} else {
Interceptor[] interceptors =registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
instance = new DefaultAdvisorAdapterRegistry();
public DefaultAdvisorAdapterRegistry() {
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
@Override
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()]);
}
目标对象方法的调用
public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)
throws Throwable {
// 通过反射机制来获得相应的方法,并调用invoke
try {
ReflectionUtils.makeAccessible(method);
return method.invoke(target, args);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
catch (IllegalArgumentException ex) {
throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" + method + "] on target [" + target + "]", ex); } catch (IllegalAccessException ex) { throw new AopInvocationException("Could not access method [" + method + "]", ex); } }
拦截器方法执行
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
private int currentInterceptorIndex = -1;
@Override
public Object proceed() throws Throwable {
// currentInterceptorIndex初始化的长度为-1,下面就就是判断 //interceptorsAndDynamicMethodMatchers长度是否为0
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
//匹配是否为正确的方法逻辑,(MethodMatcher)可以看出为匹配如果不是就调用下一个
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
//匹配失败,跳过这个拦截器,继续下一个
return proceed();
}
}
else {
// 如果是interceptor,则调用invoke方法,这是为了兼容
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}