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;

最低0.47元/天 解锁文章
621

被折叠的 条评论
为什么被折叠?



