Cglib中对jdk反射机制做了封装和调整,使用起来更加简单,同时性能也有所提升.如下为代码样例,基于cglib-2.1.3和asm-1.5.3:
1. 创建对象实例:
//通过cglib创建实例 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); //创建fastClass实例,底层将根据TestObject.class字节码信息创建一个新的class: //com.test.TestObject$$FastClassByCGLIB$$8bdfd246 //此FastClassByCGLIB类被加载后,将会被缓存起来 //缓存为一个二级map,key依次为classLoader/原始的类全名(比如com.test.TestObject) FastClass fastClass = FastClass.create(classLoader,TestObject.class); //-----------default constructor---------- FastConstructor defaultConstructor = fastClass.getConstructor(new Class[]{}); TestObject o1 = (TestObject)defaultConstructor.newInstance(); System.out.println(o1.testMethod()); //直接通过newInstance也可以创建对象,底层实现一样,找到默认的FastConstructor TestObject o2 = (TestObject)fastClass.newInstance(); System.out.println(o2.testMethod());
//------------paramter constuctor---------- FastConstructor paramsConstructor = fastClass.getConstructor(new Class[]{String.class}); TestObject o3 = (TestObject)paramsConstructor.newInstance(new Object[]{"newInstance"});//传递参数 System.out.println(o3.testMethod()); //通过newInstance方式 TestObject o4 = (TestObject)fastClass.newInstance(new Class[]{String.class},new Object[]{"newInstance"}); System.out.println(o4.testMethod());
2. 方法调用:
ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); TestObject testObject = new TestObject("testMethod"); FastClass fastClass = FastClass.create(classLoader,TestObject.class); //getMethod方法每次都会新建一个FastMethod对象,底层仍然继续jdk-reflect //和JDK-reflect相比此处性能并没有太多的提升. // FastMethod testMethod = fastClass.getMethod("testMethod", new Class[]{});//获得testMethod方法,无参数 //testMethod.getJavaMethod();//获取java api中Method引用 String result = (String)testMethod.invoke(testObject, null); System.out.println("invoke result:" + result);
//static method FastMethod staticMethod = fastClass.getMethod("testStaticMethod", new Class[]{}); staticMethod.invoke(null, null);
3. MethodDelegate样例:
/** * 简单代理(适配)工具, * 如果你的某个对象的"某个"方法,可以被某个接口所"delegate",那么你可以使用此方式. * 需要注意,"delegate"接口,只能被代理一个方法(即接口只能有一个方法,且签名和被代理者一致) * * 非常有用的方式,不过因为cglib内部缓存的机制,任何一个对象的同一个方法的delegate,事实上是同一个. */ public static void methodDelegate(){ TestObject testObject = new TestObject("methodDelegate"); //接口TestInterface与TestObject中,"testMethod"的签名和返回值类型必须一致. TestInterface delegate = (TestInterface)MethodDelegate.create(testObject, "testMethod", TestInterface.class); delegate.testMethod(); System.out.println(delegate.toString()); //静态方法 TestStaticInterface staticDelegate = (TestStaticInterface)MethodDelegate.createStatic(TestObject.class, "testStaticMethod", TestStaticInterface.class); staticDelegate.testStaticMethod(); } static interface TestInterface{ public String testMethod(); } static interface TestStaticInterface{ public String testStaticMethod(); }