• JdkDynamicAopProxy与CglibAopProxy详解


     https://blog.csdn.net/W85264/article/details/114835055

    1. Spring AOP设计
    2. JdkDynamicAopProxy与CglibAopProxy介绍

    3.CgLib实现AOP

    4.JdkDynamicAopProxy 拦截器链的获得与递归执行

    要点:cglib和jdk动态代理它们都是通过运行时,动态创建出来的代理对象的class,然后创建出代理对象。

    不同点在于:jdk创建出的代理对象是和被代理对象平级的,因为它们都是同一个接口的实现类;cglib创建出来的代理对象是被代理对象的子类(父子关系)

    代理方法的不同实现原理:jdk动态代理方法的原理是通过invock方法实现的。代理对象执行任何方法时,都会被 invock方法所拦截,然后都去执行invoke方法;cglib是通过监听执行回调,来达到动态代理方法的

    代码块1:createAopProxy() 

    DefaultAopProxyFactory.class
    /**
     * Default {@link AopProxyFactory} implementation, creating either a CGLIB proxy
     * or a JDK dynamic proxy.
     *
     * <p>Creates a CGLIB proxy if one the following is true for a given
     * {@link AdvisedSupport} instance:
     * <ul>
     * <li>the {@code optimize} flag is set
     * <li>the {@code proxyTargetClass} flag is set
     * <li>no proxy interfaces have been specified
     * </ul>
     *
     * <p>In general, specify {@code proxyTargetClass} to enforce a CGLIB proxy,
     * or specify one or more interfaces to use a JDK dynamic proxy.
     *
     */
     //DefaultAopProxyFactory为AopProxyFactory的默认实现类, 它可以创建cglib代理或者jdk代理,
     //创建cglib代理的条件:1、设置optimize这个属性  2、设置proxyTargetClass这个属性 3、被代理对象没有实现接口   
     //(这些设置都是在 第15讲 的图1中的proxyFactoryBean中设置的)
     //通常情况下可以通过proxyTargetClass属性来设置cglib代理或者指定一个或多个接口来使用JDK动态代理。
     
     //总结一句话:根据不同的配置信息,决定返回不同类型的代理(AopProxy)
    @SuppressWarnings("serial")
    public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
     
        @Override
         //AdvisedSupport 是一些配置信息,来自于 第15讲的图1中的proxyFactoryBean
        public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
                 //判断是不是设置了Optimize、isProxyTargetClass属性、没有实现接口,这些判断条件在对上面这个类的介绍信息中有提到
            if (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.");
                }
                       //如果目标类是一个接口,则创建jdk的AopProxy。
                       //这种情况很少,这种情况就是对一个接口进行代理。也就是说被代理对象是一个接口。在配置文件中的体现就是第15讲的图1中的proxyFactoryBean
                       //中的target属性引用的Mytarget的class属性是一个接口
                if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                    return new JdkDynamicAopProxy(config);
                }
                       //创建cblib的AopProxy
                       //很简单,跟JdkDynamicAopProxy的创建差不多,也是调用一个构造方法而已,不多做介绍了
                return new ObjenesisCglibAopProxy(config);
            }
            else {
                      //创建jdk的AopProxy
                      //很简单,调用JdkDynamicAopProxy的构造方法,把配置信息赋值给JdkDynamicAopProxy的一个成员属性
                return new JdkDynamicAopProxy(config);
            }
        }
     
        /**
         * Determine whether the supplied {@link AdvisedSupport} has only the
         * {@link org.springframework.aop.SpringProxy} interface specified
         * (or no proxy interfaces specified at all).
         */
        private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
            Class<?>[] ifcs = config.getProxiedInterfaces();
            return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
        }
     
    }

    代码块2:getProxy()

    ProxyFactoryBean.class
    /**
         * Return the proxy object to expose.
         * <p>The default implementation uses a {@code getProxy} call with
         * the factory's bean class loader. Can be overridden to specify a
         * custom class loader.
         * @param aopProxy the prepared AopProxy instance to get the proxy from
         * @return the proxy object to expose
         * @see AopProxy#getProxy(ClassLoader)
         */
      //返回要公开的代理对象,默认实现使用getProxy()调用工厂的bean类加载器。可以重写以指定自定义类装入器。
      //通过准备好的AopProxy实例,来获取代理返回要公开的代理对象
        protected Object getProxy(AopProxy aopProxy) {
                 //this.proxyClassLoader:  当前ProxyFactoryBean的类加载器
                 //通过AopProxy的getProxy()方法就可以创建不同的代理对象了(因为AopProxy有不同的类型)
                 //见 内部代码块1、内部代码块2
            return aopProxy.getProxy(this.proxyClassLoader);
        }
     
     内部代码块1: getProxy()
     JdkDynamicAopProxy.class
      @Override
        public Object getProxy(@Nullable ClassLoader classLoader) {
            if (logger.isTraceEnabled()) {
                logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
            }
              //获取代理对象的接口
            Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
              //查找定义好的eqauls()和hashCode()方法,因为动态代理对eqauls()和hashCode()的处理跟其他地方有点不一样,想深入研究可以自行百度
            findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
              //通过调用Proxy的newProxyInstance()方法创建代理对象(这里其实就是调用了,jdk的动态代理的方法,换句话说,java自带的jdk原生的动态代理就是这样)
              //你会发现,jdk动态代理的第三个参数InvocationHandler变成了this,所以可以看出JdkDynamicAopProxy就是InvocationHandler的一个实现类。所以
              //JdkDynamicAopProxy中一定实现了invoke()方法。因为代理对象本身并没有实现方法的代码,所有的方法的执行都是通过invoke()方法实现的。
              //JdkDynamicAopProxy中的invoke()方法详细,见 第17讲->代码块1
            return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
        }
     
     内部代码块2: getProxy()
     CglibAopProxy.class
     @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");
     
                Class<?> proxySuperClass = rootClass;
                if (ClassUtils.isCglibProxyClass(rootClass)) {
                    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...
                       //这个是cglib里面的一个对象
                Enhancer enhancer = createEnhancer();
                if (classLoader != null) {
                    enhancer.setClassLoader(classLoader);
                    if (classLoader instanceof SmartClassLoader &&
                            ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
                        enhancer.setUseCache(false);
                    }
                }
                       //给cglib的Enhancer对象设值(就像jdk动态代理时,做一些准备工作设置值一样)
                enhancer.setSuperclass(proxySuperClass);
                enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
                enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
                enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
                        //获取回调(这个好像很重要,cglib对目标对象方法的代理就是通过这些回调来完成的。jdk对目标对象方法的代理是通过invoke()方法实现的)
                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.
                       //这个方法内部会通过调用Enhancer的create()方法来创建代理对象
                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);
            }
        }
  • 相关阅读:
    Beans
    Redis记录-Redis命令
    Redis记录-Redis介绍
    RESTful记录-RESTful服务
    RESTful记录-RESTful内容
    RESTful记录-RESTful介绍
    HTTP记录-HTTP介绍
    Solr记录-solr检索和查询数据
    Solr记录-solr文档xml
    Solr记录-solr内核与索引
  • 原文地址:https://www.cnblogs.com/kelelipeng/p/16554212.html
Copyright © 2020-2023  润新知