springAOP源码2

作者: 念䋛 | 来源:发表于2021-09-20 08:27 被阅读0次

    上一节分析到创建代理
    Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
    createProxy方法的最后一行代码
    public Object getProxy(@Nullable ClassLoader classLoader) {
    return createAopProxy().getProxy(classLoader);
    }
    createAopProxy方法决定使用JDK代理还是Cglib代理

    @Override
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    // 1.config.isProxyTargetClass()的判断
    //ConfigurationClassPostProcessor#enhanceConfigurationClasses中configBeanDefs为完
    //全配置类的集合(@Configuration标注的类),遍历configBeanDefs执行
    //beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, //Boolean.TRUE);代码,在AutoProxyUtils#shouldProxyTargetClass方法中获取,返回true
    //返回true的话在AbstractAutoProxyCreator#createProxy 方法中执行//proxyFactory.setProxyTargetClass(true);
    //简单总结当标注@Configuration类config.isProxyTargetClass()返回true
    //@EnableAspectJAutoProxy(proxyTargetClass=true)所有的类都返回true
    // 2.hasNoUserSuppliedProxyInterfaces 类实现了接口,实现则返回true
       if (!IN_NATIVE_IMAGE &&
             (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
          Class<?> targetClass = config.getTargetClass();
          if (targetClass == null) {
             throw new AopConfigException("TargetSource cannot determine target class: " +
                   "Either an interface or a target is required for proxy creation.");
          }
    //如果类为接口或者是Proxy类
          if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
             return new JdkDynamicAopProxy(config);
          }
          return new ObjenesisCglibAopProxy(config);
       }
       else {
          return new JdkDynamicAopProxy(config);
       }
    }
    

    决定使用哪种动态代理,继续调用createAopProxy().getProxy(classLoader);
    首先分析JdkDynamicAopProxy动态代理,代理很简单

    @Override
    public Object getProxy(@Nullable ClassLoader classLoader) {
       if (logger.isTraceEnabled()) {
          logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
       }
    //JDK的动态代理,这里要注意的是入参为this,就是方法在执行的时候需要调用本类的
    //(JdkDynamicAopProxy) invoke方法
       return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
    }
    

    Invoke方法 分析多个Advice的调用链
    Invoke的关键代码

    //通过方法名称获取Advice
    List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
    //为了调用链实例化ReflectiveMethodInvocation
    MethodInvocation invocation =
          new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
    // 调用链的开始
    retVal = invocation.proceed();
    

    retVal为ReflectiveMethodInvocation

    @Override
    @Nullable
    public Object proceed() throws Throwable {
       // We start with an index of -1 and increment early.
       if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
    //如果调用链结束,则调用实际的方法
          return invokeJoinpoint();
       }
    // interceptorsAndDynamicMethodMatchers 要调用实际方法所要经历的拦截器集合是List //++this.currentInterceptorIndex每调用一次索引加一
       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;
          Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
          if (dm.methodMatcher.matches(this.method, 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.
    //传的this,这是链路的关键, interceptorOrInterceptionAdvice的invoke都会调用
    // invocation.proceed();方法,那有回调了这个方法,形成链路
          return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
       }
    }
    
    

    interceptorsAndDynamicMethodMatchers的集合,我们先不关心第一个,仔细看顺序,
    MethodBeforeAdviceInterceptor
    AspectJAfterAdvice
    AspectJAfterThrowingAdvice
    在以前的版本,顺序是调过来了,
    AspectJAfterThrowingAdvice
    AspectJAfterAdvice
    MethodBeforeAdviceInterceptor
    (没有实际验证过只是相关的文章),两个版本的区别,我认为老版本
    AspectJAfterThrowingAdvice把所有方法都trycatch了,也就是AspectJAfterAdvice和MethodBeforeAdviceInterceptor的异常也捕获了,而这个版本,只捕获了实际调用方法的异常
    [图片上传失败...(image-ee5114-1632043197037)]
    MethodBeforeAdviceInterceptor

    @Override
    @Nullable
    public Object invoke(MethodInvocation mi) throws Throwable {
    //实际方法之前调用before方法
      this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
    //上面说过,因为传的是this那mi就为ReflectiveMethodInvocation,回调了proeed方法
      return mi.proceed();
    }
    
    

    AspectJAfterAdvice

    @Override
    @Nullable
    public Object invoke(MethodInvocation mi) throws Throwable {
       try {
    //继续回调
         return mi.proceed();
       }
    //在finally中执行后置通知
      finally {
          invokeAdviceMethod(getJoinPointMatch(), null, null);
       }
    }
    
    

    AspectJAfterThrowingAdvice

    @Override
    @Nullable
    public Object invoke(MethodInvocation mi) throws Throwable {
       try {
    //因为这里AspectJAfterThrowingAdvice为最后一个Advice,再执行mi.proceed()判断是最后//,就会调用实际方法,也就是AspectJAfterThrowingAdvice只捕获了实际方法的异常,是否还//AspectJAfterAdvice方法是再finally中,就算发生异常也一定会执行,
    //通知当然也会执行
         return mi.proceed();
       }
       catch (Throwable ex) {
    //当实际调用的方法发生异常的时候,调用invokeAdviceMethod方法,
         if (shouldInvokeOnThrowing(ex)) {
             invokeAdviceMethod(getJoinPointMatch(), null, ex);
          }
          throw ex;
       }
    }
    

    ObjenesisCglibAopProxy代理,相比较复杂一点
    首先举个例子Enhancer增强类

    public class MyMethodIntercpetor implements MethodInterceptor {
        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            System.out.println ("MyMethodIntercpetor拦截器---方法执行之前---拦截的是Hello的sayHello方法");
            Object invoke = methodProxy.invokeSuper (o, objects);
            System.out.println ("MyMethodIntercpetor拦截器---方法执行之后---拦截的是Hello的sayHello方法");
            return invoke;
        }
        public static void main(String[] args) {
            System.setProperty (DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\cglib");
            Enhancer enhancer = new Enhancer ();
            enhancer.setSuperclass (Hello.class);
            MyMethodIntercpetor myMethodIntercpetor = new MyMethodIntercpetor ();
            HelloMethodIntercpetor helloMethodIntercpetor = new HelloMethodIntercpetor ();
    //设置callback数组是需要设置filter,调用方法时,判断使用哪个拦截器,CallbackFilter的
    //accept方法返回的时数组的下角标,这是在创建代理类的时候就规定好具体使用哪个//Interceptor,
            Callback[] callback = new Callback[]{myMethodIntercpetor, helloMethodIntercpetor};
            enhancer.setCallbacks (callback);
            enhancer.setCallbackFilter (new CallbackFilterImpl ());
            //如果时单个callback不需要filter
            Hello hello = ( Hello ) enhancer.create ();
            hello.sayHello ();
        }
    }
    class Hello {
        public void sayHello() {
            System.out.println ("sayHello");
        }
    
        public void sayWorld() {
            System.out.println ("sayWorld");
        }
    }
    class HelloMethodIntercpetor implements MethodInterceptor {
        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            System.out.println ("HelloMethodIntercpetor拦截器---方法执行之前");
            Object invoke = methodProxy.invokeSuper (o, objects);
            System.out.println ("HelloMethodIntercpetor拦截器---方法执行之后");
            return invoke;
        }
    }
    class CallbackFilterImpl implements CallbackFilter {
        @Override
        public int accept(Method method) {
    //因为有两个callback,当调用sayHello方法的是,return 0 会调用第一个callback,这是再增强类的时候就已经定好了,而不是再调用sayHello方法的时候,在到这里判断调用那个callback
           if (method.getName ().equals ("sayHello")) {
                return 0;
            } else {
                return 1;
            }
        }
    }
    

    那ObjenesisCglibAopProxy的getProxy方法也是类似的

    @Override
    public Object getProxy(@Nullable ClassLoader classLoader) {
       if (logger.isTraceEnabled()) {
          logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
       }
    
       try {
          Class<?> rootClass = this.advised.getTargetClass();
          Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
    //因为rootClass可能是被@Configuration标注,就是本身已经是增强类了,这里我们获取了原始类
          Class<?> proxySuperClass = rootClass;
          if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
             proxySuperClass = rootClass.getSuperclass();
             Class<?>[] additionalInterfaces = rootClass.getInterfaces();
             for (Class<?> additionalInterface : additionalInterfaces) {
                this.advised.addInterface(additionalInterface);
             }
          }
    
          // Validate the class, writing log messages as necessary.
          validateClassIfNecessary(proxySuperClass, classLoader);
    
          // Configure CGLIB Enhancer...
          Enhancer enhancer = createEnhancer();
          if (classLoader != null) {
             enhancer.setClassLoader(classLoader);
             if (classLoader instanceof SmartClassLoader &&
                   ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
                enhancer.setUseCache(false);
             }
          }
          enhancer.setSuperclass(proxySuperClass);
          enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
          enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
          enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
    //获取了callbacks,这里我们只关注数组的第一个Callback DynamicAdvisedInterceptor
    //因为在下面的setCallbackFilter方法中,都返回了0,其余的我也没有研究过
    //也就是实际要调用的方法,都会走DynamicAdvisedInterceptor的intercept方法
          Callback[] callbacks = getCallbacks(rootClass);
          Class<?>[] types = new Class<?>[callbacks.length];
          for (int x = 0; x < types.length; x++) {
             types[x] = callbacks[x].getClass();
          }
          // fixedInterceptorMap only populated at this point, after getCallbacks call above
          enhancer.setCallbackFilter(new ProxyCallbackFilter(
                this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
          enhancer.setCallbackTypes(types);
    
          // Generate the proxy class and create a proxy instance.
          return createProxyClassAndInstance(enhancer, callbacks);
       }
       catch (CodeGenerationException | IllegalArgumentException ex) {
          throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
                ": Common causes of this problem include using a final class or a non-visible class",
                ex);
       }
       catch (Throwable ex) {
          // TargetSource.getTarget() failed
          throw new AopConfigException("Unexpected AOP exception", ex);
       }
    }
    
    

    DynamicAdvisedInterceptor的intercept方法和Jdk动态代理是一样的,利用调用链完成拦截功能.
    Intercept方法
    主要方法,就是下面的方法

    retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
    

    点进去proceed方法,发现了supper.proceed()再点进去发现依然调用的是
    ReflectiveMethodInvocation的proceed方法,就和上面介绍的jdk动态代理执行调用链一致了,这里就不介绍了.

    相关文章

      网友评论

        本文标题:springAOP源码2

        本文链接:https://www.haomeiwen.com/subject/hjhpgltx.html