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); } }