spring的aop是使用代理对象
两种代理方式
jdk动态代理
cglib代理
jdk动态代理为例,理解代理的调用过程。
JdkDynamicAopProxy.(Object proxy, Method method, Object[] args)
判断是equals方法,不增强,直接返回。
if (!this.equalsDefined && AopUtils.isEqualsMethod(method))
判断是hashCode方法,直接返回。
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method))
...
是否需要暴露代理对象
if (this.advised.exposeProxy)
获取方法上的拦截器链
// Get the interception chain for this method. List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
缓存中取拦截器链,缓存中有拦截器链直接返回,缓冲中没有就调用etInterceptorsAndDynamicInterceptionAdvice方法去获取,并把获取到的拦截器链放入缓存中。
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;
} 拦截器链为空,直接通过反射调用方法
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
} 拦截器链不为空,创建反射的方法调用
// We need to create a method invocation... invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); // Proceed to the joinpoint through the interceptor chain. retVal = invocation.proceed();
创建对象过程
//invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
//具体的构造方法
protected ReflectiveMethodInvocation(
Object proxy, Object target, Method method, Object[] arguments,
Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {
//代理对象
this.proxy = proxy;
//目标对象
this.target = target;
//目标类
this.targetClass = targetClass;
//调用的方法
this.method = BridgeMethodResolver.findBridgedMethod(method);
//调用的参数
this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments);
//方法匹配器
this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
} 重点步骤、增强的实现、拦截器链的调用。全部增强都会在这里实现完,返回。before、after、throw、环绕。
@Override
public Object proceed() throws Throwable {
// 从-1开始。We start with an index of -1 and increment early.
//判断拦截器链执行完毕
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 从拦截器链中拿出一个拦截器、并把下标++1
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);
}
}