转载

spring源码-springAop-Invoke方法

spring的aop是使用代理对象

两种代理方式

jdk动态代理

cglib代理

jdk动态代理为例,理解代理的调用过程。

JdkDynamicAopProxy.(Object proxy, Method method, Object[] args)
  1. 判断是equals方法,不增强,直接返回。

    if (!this.equalsDefined &&  AopUtils.isEqualsMethod(method))
  2. 判断是hashCode方法,直接返回。

    else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method))

    ...

  3. 是否需要暴露代理对象

    if (this.advised.exposeProxy)
  4. 获取方法上的拦截器链

    // Get the interception chain for this method.
    List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
  5. 缓存中取拦截器链,缓存中有拦截器链直接返回,缓冲中没有就调用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;
          }
  6. 拦截器链为空,直接通过反射调用方法

    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);
                }
  7. 拦截器链不为空,创建反射的方法调用

    // 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();
  8. 创建对象过程

    //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;
        }
  9. 重点步骤、增强的实现、拦截器链的调用。全部增强都会在这里实现完,返回。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);
            }
        }

    spring源码-springAop-Invoke方法

原文  https://segmentfault.com/a/1190000022602880
正文到此结束
Loading...