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