springAOP-CGLIB代理源码分析

在AOP3里我提到了proxy-target-class属性,这个属性的值决定是继承接口的还是基于类的代理被创建。

(1)如果为true,那么使用cglib的动态代理。

(2)如果为true为false或这不设置,那么aop根据类是否继承接口决定用哪一种代理方式。

那么cglib的代理方式是怎么实现的呢,一起来探究一下:

jdk的动态代理是用反射实现的,这里就不展开叙述了,先来写一段cglib的代理实现代码:

//先写个被拦截的service
public class TestCglibService {
    public void test() {
        System.out.println("开始执行TestCglibService..."); 
    
    }
 }
 //定义一个CglibProxy动态代理类,并且让它继承MethodInterceptor
 public class CglibProxy implements MethodInterceptor{
    //被代理的目标对象
    private Object targetObject ;
    public Object createProxyInstance(Object targetObject) {
           this.targetObject = targetObject;
           Enhancer enhancer = new Enhancer();
           enhancer.setSuperclass(targetObject.getClass());// 设置代理目标
           enhancer.setCallback(this);// 设置回调
           return enhancer.create();
    } 
    

    @Override
    public Object intercept(Object object, Method method, Object[] args,
            MethodProxy methodproxy) throws Throwable {        
        Object result = null;    
        try {
              // before方法  
              System.out.println("before ...");
              result = methodproxy.invoke( targetObject , args);//执行目标对象的方法
              // after方法  
              System.out.println("after ...");
           } catch (Exception e) {
               System.out.println("异常处理 ...");
           } finally {
               System.out.println("调用结束 ...");
           }
           return result; 
       }   
   }
public class test {
    public static void main(String[] args) {
        //1-实例化需要被代理的类
        TestCglibService testCglibService = new TestCglibService();
        //2-实例化代理工厂
        CglibProxy cglibProxy = new CglibProxy();
        //3-动态生成一个代理类,并从Object强制转型成父类型
        TestCglibService testService =(TestCglibService)cglibProxy.createProcy(testCglibService);
       
        //4-执行动态代理类的方法
        testService.test();
    }
    
}

      Enhancer类是Cglib中的一个字节码增强器,在调用setSuperclass和setCallback设置代理目标和回调类之后,进入create方法中中:

public Object create() {
        this.classOnly = false;
        this.argumentTypes = null;
        return this.createHelper();
}


private Object createHelper() {
        this.preValidate();
        //根据当前的配置形成一个key,这样可以利用缓存来存数据。
        Object key = KEY_FACTORY.newInstance(this.superclass != null ? this.superclass.getName() : null, ReflectUtils.getNames(this.interfaces), this.filter == ALL_ZERO ? null : new WeakCacheKey(this.filter), this.callbackTypes, this.useFactory, this.interceptDuringConstruction, this.serialVersionUID);
        this.currentKey = key;
        Object result = super.create(key);
        return result;
    }

 

 protected Object create(Object key) {
        try {
            //获取当前的类加载器
            ClassLoader loader = this.getClassLoader();
            //尝试从缓存中获取类加载数据
            Map<ClassLoader, AbstractClassGenerator.ClassLoaderData> cache = CACHE;
            AbstractClassGenerator.ClassLoaderData data = (AbstractClassGenerator.ClassLoaderData)cache.get(loader);
            if (data == null) {
                Class var5 = AbstractClassGenerator.class;
                synchronized(AbstractClassGenerator.class) {
                    cache = CACHE;
                    data = (AbstractClassGenerator.ClassLoaderData)cache.get(loader);
                    //再次尝试获取,再次获取不到会根据当前类加载器loader生成ClassLoaderData对象,放到缓存。
                    if (data == null) {
                        Map<ClassLoader, AbstractClassGenerator.ClassLoaderData> newCache = new WeakHashMap(cache);
                        data = new AbstractClassGenerator.ClassLoaderData(loader);
                        newCache.put(loader, data);
                        CACHE = newCache;
                    }
                }
            }
            //生成一个代理类
            this.key = key;
            //获取字节码
            Object obj = data.get(this, this.getUseCache());
            return obj instanceof Class ? this.firstInstance((Class)obj) : this.nextInstance(obj);
        } catch (RuntimeException var9) {
            throw var9;
        } catch (Error var10) {
            throw var10;
        } catch (Exception var11) {
            throw new CodeGenerationException(var11);
        }
    }
 public ClassLoaderData(ClassLoader classLoader) {
            if (classLoader == null) {
                throw new IllegalArgumentException("classLoader == null is not yet supported");
            } else {
                this.classLoader = new WeakReference(classLoader);
                //定义了一个方法对象,apply方法中定义了具体逻辑。
                Function<AbstractClassGenerator, Object> load = new Function<AbstractClassGenerator, Object>() {
                    public Object apply(AbstractClassGenerator gen) {
                        // 产生字节码文件
                        Class klass = gen.generate(ClassLoaderData.this);
                        return gen.wrapCachedClass(klass);
                    }
                };
                this.generatedClasses = new LoadingCache(GET_KEY, load);
            }
        }

   

  protected Class generate(AbstractClassGenerator.ClassLoaderData data) {
        Object save = CURRENT.get();
        CURRENT.set(this);

        Class var8;
        try {
            ClassLoader classLoader = data.getClassLoader();
            if (classLoader == null) {
                throw new IllegalStateException("ClassLoader is null while trying to define class " + this.getClassName() + ". It seems that the loader has been expired from a weak reference somehow. Please file an issue at cglib's issue tracker.");
            }

            String className;
            synchronized(classLoader) {
                className = this.generateClassName(data.getUniqueNamePredicate());
                data.reserveName(className);
                this.setClassName(className);
            }

            Class gen;
            if (this.attemptLoad) {
                try {
                    gen = classLoader.loadClass(this.getClassName());
                    Class var25 = gen;
                    return var25;
                } catch (ClassNotFoundException var20) {
                    ;
                }
            }

            byte[] b = this.strategy.generate(this);
            className = ClassNameReader.getClassName(new ClassReader(b));
            ProtectionDomain protectionDomain = this.getProtectionDomain();
            synchronized(classLoader) {
                if (protectionDomain == null) {
                    gen = ReflectUtils.defineClass(className, b, classLoader);
                } else {
                    gen = ReflectUtils.defineClass(className, b, classLoader, protectionDomain);
                }
            }

            var8 = gen;
        } catch (RuntimeException var21) {
            throw var21;
        } catch (Error var22) {
            throw var22;
        } catch (Exception var23) {
            throw new CodeGenerationException(var23);
        } finally {
            CURRENT.set(save);
        }

        return var8;
    }


​​​​DefaultNamingPolicy的getClassName方法:

 public String getClassName(String prefix, String source, Object key, Predicate names) {
        if (prefix == null) {
            prefix = "org.springframework.cglib.empty.Object";
        } else if (prefix.startsWith("java")) {
            prefix = "$" + prefix;
        }
        //source截取得到的是..+ "$$"+EnhancerByCGLIB+ Integer.toHexString..
        //this.getTag()返回的是"ByCGLIB"
        String base = prefix + "$$" + source.substring(source.lastIndexOf(46) + 1) + this.getTag() + "$$" + Integer.toHexString(STRESS_HASH_CODE ? 0 : key.hashCode());
        String attempt = base;

        for(int var7 = 2; names.evaluate(attempt); attempt = base + "_" + var7++) {
            ;
        }

        return attempt;
    }

    最后在defineClass中实现对类的加载:

  public static Class defineClass(String className, byte[] b, ClassLoader loader, ProtectionDomain protectionDomain) throws Exception {
        Object[] args;
        Class c;
        //如果DEFINE_CLASS不为null,利用此Method的反射方法。
        if (DEFINE_CLASS != null) {
            args = new Object[]{className, b, new Integer(0), new Integer(b.length), protectionDomain};
            c = (Class)DEFINE_CLASS.invoke(loader, args);
        } else {
            if (DEFINE_CLASS_UNSAFE == null) {
                throw new CodeGenerationException(THROWABLE);
            }

            args = new Object[]{className, b, new Integer(0), new Integer(b.length), loader, protectionDomain};
            c = (Class)DEFINE_CLASS_UNSAFE.invoke(UNSAFE, args);
        }
        //把该类加载到jvm中。
        Class.forName(className, true, loader);
        return c;
    }
//底层用asm框架对类做处理
public void generateClass(ClassVisitor v) throws Exception {
        Class sc = this.superclass == null ? Object.class : this.superclass;
        if (TypeUtils.isFinal(sc.getModifiers())) {
            throw new IllegalArgumentException("Cannot subclass final class " + sc.getName());
        } else {
            List constructors = new ArrayList(Arrays.asList(sc.getDeclaredConstructors()));
            this.filterConstructors(sc, constructors);
            List actualMethods = new ArrayList();
            List interfaceMethods = new ArrayList();
            final Set forcePublic = new HashSet();
            getMethods(sc, this.interfaces, actualMethods, interfaceMethods, forcePublic);
            //Modifier类中,1024、256、32、16分别表示abstract、native、synchronized、final修饰符,在这会把上述几种类型统一加上final修饰符做处理
            List methods = CollectionUtils.transform(actualMethods, new Transformer() {
                public Object transform(Object value) {
                    Method method = (Method)value;
                    int modifiers = 16 | method.getModifiers() & -1025 & -257 & -33;
                    if (forcePublic.contains(MethodWrapper.create(method))) {
                        modifiers = modifiers & -5 | 1;
                    }

                    return ReflectUtils.getMethodInfo(method, modifiers);
                }
            });
            ClassEmitter e = new ClassEmitter(v);
            if (this.currentData == null) {
                e.begin_class(46, 1, this.getClassName(), Type.getType(sc), this.useFactory ? TypeUtils.add(TypeUtils.getTypes(this.interfaces), FACTORY) : TypeUtils.getTypes(this.interfaces), "<generated>");
            } else {
                e.begin_class(46, 1, this.getClassName(), (Type)null, new Type[]{FACTORY}, "<generated>");
            }

            List constructorInfo = CollectionUtils.transform(constructors, MethodInfoTransformer.getInstance());
            e.declare_field(2, "CGLIB$BOUND", Type.BOOLEAN_TYPE, (Object)null);
            e.declare_field(9, "CGLIB$FACTORY_DATA", OBJECT_TYPE, (Object)null);
            if (!this.interceptDuringConstruction) {
                e.declare_field(2, "CGLIB$CONSTRUCTED", Type.BOOLEAN_TYPE, (Object)null);
            }

            e.declare_field(26, "CGLIB$THREAD_CALLBACKS", THREAD_LOCAL, (Object)null);
            e.declare_field(26, "CGLIB$STATIC_CALLBACKS", CALLBACK_ARRAY, (Object)null);
            if (this.serialVersionUID != null) {
                e.declare_field(26, "serialVersionUID", Type.LONG_TYPE, this.serialVersionUID);
            }

            for(int i = 0; i < this.callbackTypes.length; ++i) {
                e.declare_field(2, getCallbackField(i), this.callbackTypes[i], (Object)null);
            }

            e.declare_field(10, "CGLIB$CALLBACK_FILTER", OBJECT_TYPE, (Object)null);
            if (this.currentData == null) {
                this.emitMethods(e, methods, actualMethods);
                this.emitConstructors(e, constructorInfo);
            } else {
                this.emitDefaultConstructor(e);
            }

            this.emitSetThreadCallbacks(e);
            this.emitSetStaticCallbacks(e);
            this.emitBindCallbacks(e);
            if (this.useFactory || this.currentData != null) {
                int[] keys = this.getCallbackKeys();
                this.emitNewInstanceCallbacks(e);
                this.emitNewInstanceCallback(e);
                this.emitNewInstanceMultiarg(e, constructorInfo);
                this.emitGetCallback(e, keys);
                this.emitSetCallback(e, keys);
                this.emitGetCallbacks(e);
                this.emitSetCallbacks(e);
            }

            e.end_class();
        }
    }

     到这一步,生成类文件并返回。接下来调用方法时,会回调定义好的intercept方法,到MethodProxy中的invoke方法:

 public Object invoke(Object obj, Object[] args) throws Throwable {
        try {
            this.init();
            MethodProxy.FastClassInfo fci = this.fastClassInfo;
            return fci.f1.invoke(fci.i1, obj, args);
        } catch (InvocationTargetException var4) {
            throw var4.getTargetException();
        } catch (IllegalArgumentException var5) {
            if (this.fastClassInfo.i1 < 0) {
                throw new IllegalArgumentException("Protected method: " + this.sig1);
            } else {
                throw var5;
            }
        }
    }


    private void init() {
        if (this.fastClassInfo == null) {
            Object var1 = this.initLock;
            synchronized(this.initLock) {
                if (this.fastClassInfo == null) {
                    MethodProxy.CreateInfo ci = this.createInfo;
                    MethodProxy.FastClassInfo fci = new MethodProxy.FastClassInfo();
                    fci.f1 = helper(ci, ci.c1);
                    fci.f2 = helper(ci, ci.c2);
                    fci.i1 = fci.f1.getIndex(this.sig1);
                    fci.i2 = fci.f2.getIndex(this.sig2);
                    this.fastClassInfo = fci;
                    this.createInfo = null;
                }
            }
        }

    }

  在init方法中,做了方法索引绑定。每个方法都有对应的index,方法调用时会首先获得具体索引。所以cglib之所以会高效,就是方法调用的处理并没有使用反射,反射调用需要经过本地方法,而Cglib采用了通过给每个代理类方法分配索引,通过index来直接查找具体方法。

总结:

cglib用开源asm框架,通过Enhancer类生成一个代理类,并让此代理类继承目标类,成为其子类。然后在代理类中采用方法拦截的技术,拦截所有父类方法的调用,横切加入我们自定义的处理逻辑。代理类将目标类作为自己的父类,并为其中的每个非final委托方法,创建两个方法:

(1)一个是与目标方法签名相同的方法,它在方法中通过super调用父类的方法。

(2)另一个是代理类独有的方法,称之为 Callback回调方法,也就是我们在 intercept() 方法中定义好的逻辑。它会判断这个方法是否绑定了拦截器(实现了 MethodInterceptor 接口的对象),如果存在,则将调用 intercept() 方法,对目标方法进行代理。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值