Java动态代理(JDKProxy与CGlibProxy)
来源:互联网 发布:ubuntu配置jdk1.8 编辑:程序博客网 时间:2024/06/12 00:44
代理模式是什么?
代理模式,也叫委托模式;看过电影 间谍之桥 一定对汤姆.汉克斯精悍的演技印象深刻,在这部电影中由他饰演詹姆士·唐纳文一个美国律师和苏联驻德官员在东德谈判;两国政府由于各种原因不能直接出面,分别派出代表来谈,但达成协议后执行实际还是由两国执行的;对象不直接交互,只负责实际操作,由代理对象交互,这就是代理模式。+ω+
上图地干活(UML):
什么是Java动态代理?
在传统的模式下,如果我们要给一个类写一个代理类,需要首先实现这个类实现的接口,然后在内部持有被代理对象,在执行方法时在代理对象中执行被代对象的方法;如果需要被代理的类很多,保证让你写到爽歪歪, ̄ω ̄,会出人命的。
Java动态代理就在这种情况下出现了,>ω<,它可以自动地给类生成代理类,这样就节省了大量时间,Spring框架中就大量使用JDKProxy和CGlibProxy技术来实现AOP(面向切面编程),来实现事务控制、日志打印等操作。
JDKProxy和CGlibProxy区别是什么?
JDKProxy是JDK提供的一种动态代理方式,不需要引入jar包,但其限制是代理类和被代理类必须实现相同接口,如果被代理类是继承的类那就抓瞎了。
CGlibProxy需要引入第三方jar包(cglib),它可以直接给代理类生成一个子类,没有必须实现自相同的接口限制。
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.2.1</version> </dependency>
JDKProxy、CGlibProxy例子。
public interface HelloService { void sayHello(String name);}//被代理类public class HelloServiceImpl implements HelloService { public void sayHello(String name) { System.out.println("Hello:"+name); }}//JDK实现方式public class JdkProxy { public static <T> T getJdkProxy(final T source) { return (T) Proxy.newProxyInstance(source.getClass().getClassLoader(), source.getClass().getInterfaces(), new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before"); Object result = method.invoke(source, args); System.out.println("end"); return result; } }); }}//cglib实现方式public class CglibProxy { public static <T> T getCglibProxy(final T source) { MethodInterceptor methodInterceptor = new MethodInterceptor() { public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { System.out.println("before"); Object result = method.invoke(source, args); System.out.println("end"); return result; } }; //创建代理对象 Enhancer enhancer = new Enhancer(); //设置代理类加载对象 enhancer.setClassLoader(source.getClass().getClassLoader()); //设置代理类继承父类 enhancer.setSuperclass(source.getClass()); //设置回调方法 enhancer.setCallback(methodInterceptor); return (T) enhancer.create(); }}
测试代码
@Test public void test1() throws IOException { HelloService helloServiceImpl = new HelloServiceImpl(); HelloService helloServiceJdkProxy = JdkProxy.getJdkProxy(helloServiceImpl); HelloService helloServiceCglibProxy = CglibProxy.getCglibProxy(helloServiceImpl); Long beginTime1 = System.nanoTime(); for (int i = 0; i < 1000000000; i++) { helloServiceImpl.sayHello("wrh"); } Long endTime1 = System.nanoTime(); Long beginTime2 = System.nanoTime(); for (int i = 0; i < 1000000000; i++) { helloServiceJdkProxy.sayHello("wrh"); } Long endTime2 = System.nanoTime(); Long beginTime3 = System.nanoTime(); for (int i = 0; i < 1000000000; i++) { helloServiceCglibProxy.sayHello("wrh"); } Long endTime3 = System.nanoTime(); System.out.println("Base:" + (endTime1 - beginTime1)); //3004676032 System.out.println("JdkProxy:" + (endTime2 - beginTime2)); //68836851401 System.out.println("CglibProxy:" + (endTime3 - beginTime3));//67284922866 }
直接调用、JDKProxy调用、CGlibProxy调用效率比较。
通过测试JDKProxy与CGlibProxy调用速度相差不大;但与直接调用差距巨大,是直接调用所耗费时间20倍。
为什么需要这么多时间呢?同时JDKProxy与CGlibProxy生成的class是什么呢?它们又是如何生成的呢?
欲知后事如何,请听下回分解。>o<
源码
0 0
- Java动态代理(JDKProxy与CGlibProxy)
- 笨鸟之AOP的JDKProxy和CGlibProxy动态代理的模拟及比较
- java [ 静态(接口)代理 ,动态(接口)代理,CglibProxy动态(实体类)代理]
- Spring 中JDKProxy和CGlibProxy的区别
- Spring 中JDKProxy和CGlibProxy的区别 .
- Spring 中JDKProxy和CGlibProxy的区别
- Spring学习笔记五(JDKProxy和cglibProxy的区别)
- Spring中AOP的JDKProxy和CGlibProxy的区别
- Java基础(十一) 代理: jdkProxy和cgLib
- Java 代理与动态代理
- Java代理与动态代理
- Java 代理与动态代理
- 代理模式与Java动态代理类
- java中的静态代理与动态代理
- 代理模式与Java动态代理类
- Java静态代理与动态代理
- java中的静态代理与动态代理
- Java静态代理与动态代理
- leetcode - Create Maximum Number
- Android WebView应用详解
- iOS dispatch队列
- 一个有意思的例子
- 把数据填到EXcel里
- Java动态代理(JDKProxy与CGlibProxy)
- java中String byte HexString的转换
- Software-Building-HOWTO_2
- Ext.grid.CheckboxSelectionModel()勾选不上
- Java提高篇-----Java集合细节(一):请为集合指定初始容量
- Round #344 (Div. 2) A - Interview
- uva 815
- 在jsp页面判断如果有信息就提示,否则不提示
- mysql,sqlserver及oracle分页查询