CGLIB(Code Generation Library)是一个开源项目!
cglib(Code Generation Library)是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。
cglib封装了asm,可以在运行期动态生成新的class。
cglib用于AOP,jdk中的proxy必须基于接口,cglib却没有这个限制, 可以是普通Java类,但是注意的是不能是非final Java类,cglib是通过继承来实现的代码增强,所代理类的方法不能使用private来修饰。
这里使用jar包:
cglib-2.2.jar
不需要使用spring参与,直接由原始的cglib通过继承增强代码类。
普通类文件:
import java.util.ArrayList; import java.util.List; public class Chinese /*implements Person*/ { protected String sayHello(String name) { System.out.println(name + ": running sayHello method "); return name + " Hello , Spring AOP(cglib)"; } void eat(String food) { System.out.println("I'm eating :" + food); } public List<String> getCharacters(String str) { List<String> list = new ArrayList<String>(4); int count = 0; while (count < 4) { list.add(str.charAt(count) + ""); count++; } System.out.println("check get characters running......"); return list; } } interface Person { String sayHello(String name); void eat(String food); List<String> getCharacters(String str); }
代理工厂类:
通过这个类合成/聚合复用原则将业务类和需要统一处理的横切面拦截器合成在一起:
import net.sf.cglib.core.DebuggingClassWriter; import net.sf.cglib.proxy.Enhancer; public class ProxyFactory { public static Object getProxyInstance(Class<?> clazz) { Enhancer en = new Enhancer(); // set target proxy en.setSuperclass(clazz); // set proxy interceptor en.setCallback(new AroundAdvice()); // create proxy instance Object o = en.create(); System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "R:\\a.class"); return o;//class com.cherrypicks.laneige.common.test3.Chinese$$EnhancerByCGLIB$$5bca626a } }
实际统一处理(拦截)方法类:
import java.lang.reflect.Method; import net.sf.cglib.core.DebuggingClassWriter; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class AroundAdvice implements MethodInterceptor { public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws java.lang.Throwable { System.out.println("-------before execute ,transaction start ..."); //execute target object method and save target object return value // Object rvt = proxy.invokeSuper(target, new String[] { "new parameter" }); Object rvt = proxy.invokeSuper(target, args); System.out.println("-------after execute, transaction end ..."); System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "R:\\"); return rvt; } }
最后实际调用、测试类:
import java.util.List; /** * interception AroundAdvice * @author [email protected] * time: 2015-05-25 17:03 */ public class CglibTest { /** * @param args */ public static void main(String[] args) { Chinese zh = (Chinese) ProxyFactory.getProxyInstance(Chinese.class); System.out.println(zh.sayHello("猪八戒")); System.out.println("\n"); zh.eat("大西瓜"); System.out.println("\n"); List<String> ss = zh.getCharacters("abcd"); System.out.println("\nreturn value:\n"); for (String s : ss) { System.out.println("character: \t" + s); } // check if generate cglib class file System.out.println(zh.getClass()); } }
=================
打印效果如下:
-------before execute ,transaction start ... 猪八戒: running sayHello method -------after execute, transaction end ... 猪八戒 Hello , Spring AOP(cglib) -------before execute ,transaction start ... I'm eating :大西瓜 -------after execute, transaction end ... -------before execute ,transaction start ... check get characters running...... -------after execute, transaction end ... return value: character: a character: b character: c character: d class com.cherrypicks.laneige.common.test3.Chinese$$EnhancerByCGLIB$$5bca626a
非常简单的逻辑代码,学习入门理解....
可以参考其他复杂实现方式,
http://www.blogjava.net/stone2083/archive/2008/03/16/186615.html
https://github.com/limingwei/li/blob/master/framework/li/aop/AopEnhancer.java