Java动态代理(二)CGLIB动态代理应用
2016-07-19 14:45
471 查看
JDK自从1.3版本开始,就引入了动态代理,JDK的动态代理用起来非常简单,但是它有一个限制,就是使用动态代理的对象必须实现一个或多个接口。如果想代理没有实现接口的类可以使用CGLIB包。
CGLIB是一个强大的高性能的代码生成包。它被许多AOP的框架(例如Spring AOP)使用,为他们提供方法的interception(拦截)。Hibernate也使用CGLIB来代理单端single-ended(多对一和一对一)关联。EasyMock通过使用模仿(moke)对象来测试java代码的包。它们都通过使用CGLIB来为那些没有接口的类创建模仿(moke)对象。
CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。
以下为模拟案例,在使用CGLIB时需引入cglib-nodep-2.1_3.jar包
定义一个HelloWorld类,注意此处是个类,而不是接口
CglibProxy类
测试类
运行结果为:
CGLIB是一个强大的高性能的代码生成包。它被许多AOP的框架(例如Spring AOP)使用,为他们提供方法的interception(拦截)。Hibernate也使用CGLIB来代理单端single-ended(多对一和一对一)关联。EasyMock通过使用模仿(moke)对象来测试java代码的包。它们都通过使用CGLIB来为那些没有接口的类创建模仿(moke)对象。
CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。
以下为模拟案例,在使用CGLIB时需引入cglib-nodep-2.1_3.jar包
定义一个HelloWorld类,注意此处是个类,而不是接口
package com.ljq.test; /** * 定义一个HelloWorld类 * * @author jiqinlin * */ public class HelloWorld { public void sayHelloWorld() { System.out.println("HelloWorld!"); } }
CglibProxy类
package com.ljq.test; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; /** * 通过Cglib实现在方法调用前后向控制台输出两句字符串 * * @author jiqinlin * */ public class CglibProxy implements MethodInterceptor { //要代理的原始对象 private Object obj; public Object createProxy(Object target) { this.obj = target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.obj.getClass());// 设置代理目标 enhancer.setCallback(this);// 设置回调 enhancer.setClassLoader(target.getClass().getClassLoader()); return enhancer.create(); } /** * 在代理实例上处理方法调用并返回结果 * * @param proxy * 代理类 * @param method * 被代理的方法 * @param params * 该方法的参数数组 * @param methodProxy */ public Object intercept(Object proxy, Method method, Object[] params, MethodProxy methodProxy) throws Throwable { Object result = null; // 调用之前 doBefore(); // 调用原始对象的方法 result = methodProxy.invokeSuper(proxy, params); // 调用之后 doAfter(); return result; } private void doBefore() { System.out.println("before method invoke"); } private void doAfter() { System.out.println("after method invoke"); } }
测试类
package com.ljq.test; public class HelloWorldTest { public static void main(String[] args) { HelloWorld helloWorld=new HelloWorld(); CglibProxy cglibProxy=new CglibProxy(); HelloWorld hw=(HelloWorld)cglibProxy.createProxy(helloWorld); hw.sayHelloWorld(); } }
运行结果为:
相关文章推荐
- springmvc3+hibernate3整合问题
- Java动态代理(一)动态类Proxy的使用
- Java逐行读写TXT文件
- Java基础知识二
- Java中equals和==的区别
- 在cmd里输入cd myclass 提示系统找不到指定路径
- java的Arrays类的应用
- Java专业术语集
- spring MVC mybatis ssm 框架 Jeeplus智能快速开发平台
- Java反射小结
- Java接口修饰符详解
- Java四种线程池的使用
- Struts-java.lang.UnsupportedClassVersionError错误
- Spring概述(1)
- eclipse运行代码时——类路径引用的归档不存在"XXXXX.jar"问题解决
- 归并排序java
- 接口(multiple)
- Spring中jdbcTemplate的用法实例(一)
- spring.net 如何让xml智能提示
- static有什么用