spring源碼-springAop-Invoke方法

spring的aop是使用代理對象
兩種代理方式
jdk動態代理
cglib代理
jdk動態代理爲例,理解代理的調用過程。spring

JdkDynamicAopProxy.(Object proxy, Method method, Object[] args)
  1. 判斷是equals方法,不加強,直接返回。緩存

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

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

    ...ide

  3. 是否須要暴露代理對象this

    if (this.advised.exposeProxy)
  4. 獲取方法上的攔截器鏈lua

    // Get the interception chain for this method.
    List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
  5. 緩存中取攔截器鏈,緩存中有攔截器鏈直接返回,緩衝中沒有就調用etInterceptorsAndDynamicInterceptionAdvice方法去獲取,並把獲取到的攔截器鏈放入緩存中。spa

    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. 攔截器鏈不爲空,建立反射的方法調用code

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

    image.png

相關文章
相關標籤/搜索