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 zxbxiaobo@sina.com
* 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