cglib动态代理:
http://blog.csdn.net/xiaohai0504/article/details/6832990
一、原理
代理为控制要访问的目标对象提供了一种途径。当访问对象时,它引入了一个间接的层。JDK自从1.3版本开始,就引入了动态代理,并且经常被用来动态地创建代理。JDK的动态代理用起来非常简单,当它有一个限制,就是使用动态代理的对象必须实现一个或多个接口。如果想代理没有实现接口的继承的类,该怎么办?现在我们可以使用CGLIB包。
二、什么是cglib
CGLIB是一个强大的高性能的代码生成包。
1>它广泛的被许多AOP的框架使用,例如:Spring AOP和dynaop,为他们提供方法的interception(拦截);
2>hibernate使用CGLIB来代理单端single-ended(多对一和一对一)关联(对集合的延迟抓取,是采用其他机制实现的);
3>EasyMock和jMock是通过使用模仿(moke)对象来测试java代码的包。
它们都通过使用CGLIB来为那些没有接口的类创建模仿(moke)对象。
三、底层
CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM(Java字节码操控框架),来转换字节码并生成新的类。除了CGLIB包,脚本语言例如 Groovy和BeanShell,也是使用ASM来生成java的字节码。当不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。所以cglib包要依赖于asm包,需要一起导入。
四、样例
1. java方式代理
package cn.jerry.mouse.dynamic_proxy.java; public interface IStudent { public void action(); }
package cn.jerry.mouse.dynamic_proxy.java; public class StudentImpl implements IStudent { @Override public void action() { System.out.println("[Student]实际方法。。。"); } }
package cn.jerry.mouse.dynamic_proxy.java; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * JDK动态代理代理类 */ public class JavaProxy implements InvocationHandler { private Object target; /** * 绑定委托对象并返回一个代理类 * * @param target * @return */ public Object bind(Object target) { this.target = target; // 取得代理对象 return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); // 要绑定接口 } @Override /** * 调用方法 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; System.out.println("【java代理】调用实际方法前"); // 执行方法 result = method.invoke(target, args); System.out.println("【java代理】调用实际方法后"); return result; } }
package cn.jerry.mouse.dynamic_proxy.java; public class TestProxy { public static void main(String[] args) { JavaProxy proxy = new JavaProxy(); IStudent student = (IStudent) proxy.bind(new StudentImpl()); student.action(); } }
2.cglib方式代理
package cn.jerry.mouse.dynamic_proxy.cglib; public class StudentImpl { public void action() { System.out.println("[Student]实际方法。。。"); } }
package cn.jerry.mouse.dynamic_proxy.cglib; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; /** * 使用cglib动态代理 * */ public class CgLibProxy implements MethodInterceptor { private Object target; /** * 创建代理对象 * * @param target * @return */ public Object getInstance(Object target) { this.target = target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.target.getClass()); // 回调方法 enhancer.setCallback(this); // 创建代理对象 return enhancer.create(); } @Override // 回调方法 public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("[cglib代理]调用实际方法前"); proxy.invokeSuper(obj, args); System.out.println("[cglib代理]调用实际方法后"); return null; } }
package cn.jerry.mouse.dynamic_proxy.cglib; public class TestProxy { public static void main(String[] args) { CgLibProxy cglib = new CgLibProxy(); StudentImpl student = (StudentImpl) cglib.getInstance(new StudentImpl()); student.action(); } }
源代码下载:http://download.csdn.net/detail/yinxing2008/7205015