Cglib源码解析

      Cglib(Code Generator Library)是一个 java字节码生成工具,提供了一系列的类生成器,可以在运行期间,生成现有java类的子类(cglib不能扩展final类)。本系列文章分析cglib的源码实现。

一、基本框架


ClassGenerator是Cglib的核心接口,其中核心方法generateClass方法用于产生目标类;

public interface ClassGenerator {
    void generateClass(ClassVisitor var1) throws Exception;
}

AbstractClassGenerator抽象类实现了ClassGenerator接口,此类中并没有实现generateClass()方法,而是使用了模板方法设计模式,protected Object create()即为模板方法,其中byte[] b=this.strategy.generate(this)会调用继承类中实现的generateClass()方法。另外,AbstractClassGenerator中定义了一个静态内部类Source,其中name字段存储ClassGenerator的实现类全名,如net.sf.cglib.proxy.Enhancer;cache缓存用于存储该ClassGenerator生成的目标类,类型仍然是一个HashMap,类型为<ClassLoader,<Object,class>>。key为加载目标类的类加载器(针对同一个目标类,使用不同的类加载器加载,得到的class文件也不相同,因为需要以ClassLoader进行区分。),value仍然是一个hashmap,其中键值一般是Cglib中定义的类Key,value为目标类。为什么需要Key类呢?对于那些只与单个类相关的生成类,可以采用类名作为key。在动态代理中生成类不仅与目标类相关,还与使用的拦截类(MethodInterceptor),过滤类(CallbackFilter)相关,这样的话就要使用multi-vaules key来标识这个生成类。

protected static class Source {
    String name;
    Map cache = new WeakHashMap();

    public Source(String name) {
        this.name = name;
    }
}

每个ClassGenerator具体实现类都有相应的缓存,如Enhancer类的静态块中定义source=new Source(Enhancer.class.getName())

二、目标类class文件的生成过程

我们以cglib动态代理为例来展示cglib生成class类文件的过程。我们有一个简单类UserServiceImp,用cglib动态生成其子类。

public class UserServiceImp {
    public String getName(int id){
        System.out.println("getName()");
        return "Tom";
    }
    public int getAge(int id){
        System.out.println("getAge()");
        return 10;
    }
}
首先需要定义一个实现拦截器实现MethodInterceptor接口,当生成的目标类调用UserServiceImp中的任何方法时都会被此类拦截,执行其中的intercept方法,此时会传入四个参数,o表示生成的目标类,method表示要调用的方法名,objects表示调用方法的参数,methodProxy要执行的方法的代理,UserServiceImp中的每个方法都会存在一个methodProxy方法代理。methodProxy.invokeSuper(o,objects)即调用真正的方法。

public class UserServiceMethodInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        Object obj=methodProxy.invokeSuper(o,objects);
        return obj;
    }
}

然后利用Enhancer生成器来生成目标类,如下所示

public class CglibDemo {
    public static void main(String[] args){
        UserServiceMethodInterceptor userServiceMethodInterceptor=new UserServiceMethodInterceptor();
        //实例化Enhancer类生成器
        Enhancer enhancer=new Enhancer();
        //设置Enhancer要生成的目标类的父类
        enhancer.setSuperclass(UserServiceImp.class);
        //设置目标类执行方法的拦截器
        enhancer.setCallback(userServiceMethodInterceptor);
        //利用enhancer生成目标类 UserServiceImp$$EnhancerByCGLIB$$b2b12b83@6df97b55
        UserServiceImp obj=(UserServiceImp) enhancer.create();
        //生成的目标类调用方法,此时会被userServiceMethodInterceptor拦截,执行其中的intercept方法
        obj.getName(1);
        //生成的目标类调用方法,此时会被userServiceMethodInterceptor拦截,执行其中的intercept方法
        obj.getAge(1);
    }
}

其中的关键方法时enhancer.create(),源码实现如下

public Object create() {
    this.classOnly = false;
    this.argumentTypes = null;
    return this.createHelper();
}
private Object createHelper() {
    //设置拦截器类
    this.validate();
    if (this.superclass != null) {
        this.setNamePrefix(this.superclass.getName());
    } else if (this.interfaces != null) {
        this.setNamePrefix(this.interfaces[ReflectUtils.findPackageProtected(this.interfaces)].getName());
    }
    //调用AbstractClassGenerator的create()方法
    return super.create(KEY_FACTORY.newInstance(this.superclass != null ? this.superclass.getName() : null, ReflectUtils.getNames(this.interfaces), this.filter, this.callbackTypes, this.useFactory, this.interceptDuringConstruction, this.serialVersionUID));
}

AbstractClassGenerator中的create方法实现如下:

protected Object create(Object key) {
    try {
        Class gen = null;
        AbstractClassGenerator.Source var3 = this.source;
        synchronized(this.source) {
            ClassLoader loader = this.getClassLoader();
            Map cache2 = null;
            cache2 = (Map)this.source.cache.get(loader);
            if (cache2 == null) {
                cache2 = new HashMap();
                ((Map)cache2).put(NAME_KEY, new HashSet());
                this.source.cache.put(loader, cache2);
            } else if (this.useCache) {
                Reference ref = (Reference)((Map)cache2).get(key);
                gen = (Class)(ref == null ? null : ref.get());
            }

            if (gen == null) {
                Object save = CURRENT.get();
                CURRENT.set(this);

                Object var24;
                try {
                    this.key = key;
                    if (this.attemptLoad) {
                        try {
                            gen = loader.loadClass(this.getClassName());
                        } catch (ClassNotFoundException var17) {
                            ;
                        }
                    }

                    if (gen == null) {
                        //this.strategy是默认的DefaultGeneratorStrategy
                        //调用其generate生成目标类的代码
                        byte[] b = this.strategy.generate(this);
                        String className = ClassNameReader.getClassName(new ClassReader(b));
                        this.getClassNameCache(loader).add(className);
                        gen = ReflectUtils.defineClass(className, b, loader);
                    }

                    if (this.useCache) {
                        //将生成的目标类添加到缓存中
                        ((Map)cache2).put(key, new WeakReference(gen));
                    }
                    //创建生成目标类的实例
                    var24 = this.firstInstance(gen);
                } finally {
                    CURRENT.set(save);
                }
                //返回生成的目标类的实例
                return var24;
            }
        }

        return this.firstInstance(gen);
    } catch (RuntimeException var20) {
        throw var20;
    } catch (Error var21) {
        throw var21;
    } catch (Exception var22) {
        throw new CodeGenerationException(var22);
    }
}

上段代码中调用了DefaultGeneratorStrategy的generate方法,源码如下:

public class DefaultGeneratorStrategy implements GeneratorStrategy {
    public static final DefaultGeneratorStrategy INSTANCE = new DefaultGeneratorStrategy();

    public DefaultGeneratorStrategy() {
    }

    public byte[] generate(ClassGenerator cg) throws Exception {
        ClassWriter cw = this.getClassWriter();
        //此处调用Enhancer的generateClass方法来生成目标类
        this.transform(cg).generateClass(cw);
        return this.transform(cw.toByteArray());
    }

    protected ClassWriter getClassWriter() throws Exception {
        return new DebuggingClassWriter(1);
    }

    protected byte[] transform(byte[] b) throws Exception {
        return b;
    }

    protected ClassGenerator transform(ClassGenerator cg) throws Exception {
        return cg;
    }
}

上段代码又调用了Enhancer的generateClass方法,源码如下:

public void generateClass(ClassVisitor v) throws Exception {
    Class sc = this.superclass == null ? (class$java$lang$Object == null ? (class$java$lang$Object = class$("java.lang.Object")) : class$java$lang$Object) : this.superclass;
    if (TypeUtils.isFinal(sc.getModifiers())) {
        throw new IllegalArgumentException("Cannot subclass final class " + sc);
    } 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);
        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);
        e.begin_class(46, 1, this.getClassName(), Type.getType(sc), this.useFactory ? TypeUtils.add(TypeUtils.getTypes(this.interfaces), FACTORY) : TypeUtils.getTypes(this.interfaces), "<generated>");
        List constructorInfo = CollectionUtils.transform(constructors, MethodInfoTransformer.getInstance());
        e.declare_field(2, "CGLIB$BOUND", Type.BOOLEAN_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);
        }

        this.emitMethods(e, methods, actualMethods);
        this.emitConstructors(e, constructorInfo);
        this.emitSetThreadCallbacks(e);
        this.emitSetStaticCallbacks(e);
        this.emitBindCallbacks(e);
        if (this.useFactory) {
            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();
    }
}
经过以上过程,Enhancer完成目标类的生成。

三、方法调用过程

当调用主函数中obj.getAge()方法时,会执行拦截器中的methodProxy.invokeSuper方法,我们看一下具体的执行过程

public class UserServiceMethodInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        Object obj=methodProxy.invokeSuper(o,objects);
        return obj;
    }
}

首先看一下MethodProxy类的部分源码,可以看到,cglib的实际执行过程是生成委托类的fastClass来进行调用

public class MthodProxy {
    public Object invokeSuper(Object obj, Object[] args) throws Throwable {
        try {
            this.init();
            MethodProxy.FastClassInfo fci = this.fastClassInfo;
            //通过fastClass调用UserServiceImp的getAge方法
            return fci.f2.invoke(fci.i2, obj, args);
        } catch (InvocationTargetException var4) {
            throw var4.getTargetException();
        }
    }
    //此方法用于生成UserServiceImp类的fastClass
    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;
                }
            }
        }

    }
}

四、FastClass的概念

JDK动态代理是使用反射的方法来调用委托类的方法,cglib通过生成FastClass的方法来调用委托类的方法。FastClass的机制是建立委托类方法的索引,通过索引来查找和调用实际的方法,这种方式比反射速度快一些,看如下代码:

public class MainTest {
    public static void main(String[] args){
        Test tt = new Test();
        FastClassDemo fc = new FastClassDemo();
        fc.invoke(fc.getIndex("f()V"), tt, null);
    }
}

class Test{
    public void f(){
        System.out.println("f method");
    }

    public void g(){
        System.out.println("g method");
    }
}
class FastClassDemo{
    public Object invoke(int index, Object o, Object[] ol){
        Test t = (Test) o;
        switch(index){
            case 1:
                t.f();
                return null;
            case 2:
                t.g();
                return null;
        }
        return null;
    }

    public int getIndex(String signature){
        switch(signature.hashCode()){
            case 3078479:
                return 1;
            case 3108270:
                return 2;
        }
        return -1;
    }
}




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值