java:动态代理的使用
来源:互联网 发布:.儿童编程小游戏 编辑:程序博客网 时间:2024/05/22 08:45
对于java
的使用,真的已经有好几年了。可以说,java
的方方面面差不多都有涉猎。但是,也有几个知识点,一直没有怎么涉及。比如:
- 动态代理
- 注解
- GUI
可能是当时学习这些的时候,带给我太多的恐惧,导致我一直不敢再碰这些东西。
不过现在回过头来,再次拾起当时让我恐惧的这些内容,没有当时那么恐惧了;相反,有一种很愉悦的感觉。
顺便说一句:
java
中应该没有所谓的”静态代理”。因为我看到网上的各种博客/教程/问答,对于静态代理的讲解,其实完全是对装饰者模式的讲解与使用而已。或者是是对聚合模式的使用而已。
闲话不多说,下面我也简单讲解一下我对动态代理的理解与使用。
DynamicProxy
Java 动态代理| jdk & cglib 两种方式实现
所谓动态代理,首先要确立一个目标就是要生成一个目标类的代理对象。
明确了这一目标,后续的实现就有了一个明确的目的性了。
- 无论是
jdk
的原生支持,还是第三方库,比如cglib
,目的都是一样的,就是生成一个目标类的代理对象。 - 拿到代理对象只后,就可以像使用目标对象一样去使用里面的方法。
- 不过既然是使用代理,就必然希望通过代理,去对目标对象对方法做一些改变,比如增强实现。(加入日志插入等)。这时候,就可以在代理实现等回调方法里面去做一些增强了。
大体上的套路就是这些。至于怎么去使用,往往要看实际应用场景了。
jdk
对动态代理的支持程度是:被代理方法,必须是接口中的方法。cglib
对动态代理对支持程度是:被代理对方法,不能是被final
修饰对方法。
好吧:下面分别给出两种实现的简单示例:
- 基于
jdk
的实现:
模拟场景:有一个
Car
类,实现类Moveable
接口。然后,通过动态代理去调用Car#move()
方法,并在方法执行的前后打印日志。
// interface movaableinterface Moveable { boolean move(String road);}// class carclass Car implements Moveable { @Override public boolean move(String road) { System.out.println("I am running in road: " + road); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return new Random().nextInt() % 2 == 0; }}// test mainpublic class TestClient { public static void main(String[] args) { Moveable m = new Car(); Class<? extends Moveable> clazz = m.getClass(); Moveable proxyInstance = (Moveable) Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("do before >>>>"); long st = System.currentTimeMillis(); Object invoke = method.invoke(m, args); long et = System.currentTimeMillis(); System.err.println("invoke = " + invoke + " , " + method + " , " + Arrays.toString(args)); System.out.println("do after <<<<<"); System.out.println(method.getName() + " 耗时: " + (et - st)); return invoke; } }); proxyInstance.move("Tokyo"); }}
jdk输出如下:
do before >>>>I am running in road: Tokyoinvoke = false , public abstract boolean com.cat.proxy.dynamic.Moveable.move(java.lang.String) , [Tokyo]do after <<<<<move 耗时: 1001
- 基于
cglib
的实现:
模拟场景:有一个Train
类,也有一个move
方法,通过动态代理,在move
方法执行前后,打印日志。
// class train class Train { public boolean move(String road) { System.out.println("I am running in road: " + road); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return new Random().nextInt() % 2 == 0; }}// test mainpublic class TestMain { public static void main(String[] args) throws InterruptedException { Train train = new Train(); proxy3(train); } private static void proxy3(Train train) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(train.getClass()); enhancer.setCallback((MethodInterceptor) (target, method, objects, methodProxy) -> { System.out.println("** do before >>> .");// Object invokeSuper = methodProxy.invokeSuper(target, objects); Object invokeSuper = method.invoke(train, objects); // 使用 method 和 methodProxy 都可以。 System.err.println((target instanceof Train) + " , " + method + " , " + Arrays.toString(objects) + " , " + methodProxy); System.out.println("** do after <<<< $ "); return invokeSuper; }); Train trainProxy = (Train) enhancer.create(); trainProxy.move("Paris"); } }
cglib输出如下
** do before >>> .I am running in road: Paris** do after <<<< $ true , public boolean com.cat.proxy.dynamic.cglib.Train.move(java.lang.String) , [Paris] , net.sf.cglib.proxy.MethodProxy@78e03bb5
最后,给出完整示例代码。
阅读全文
0 0
- java动态代理的使用
- java:动态代理的使用
- Java动态代理使用
- java动态代理使用
- [转]JAVA动态代理的使用
- Java中动态代理的使用
- java动态代理与cglib代理的简单使用
- 动态代理的使用
- Java动态代理一------动态类Proxy的使用
- Java动态代理--动态类Proxy的使用
- Java的动态代理
- JAVA的动态代理
- java的动态代理
- java的动态代理
- JAVA的动态代理
- JAVA的动态代理
- JAVA的动态代理
- JAVA的动态代理
- 半咸不咸的一天
- Linux(CenOS 7.3)安装JDK
- 弹唱
- 总结-2017/9/10
- 2017.9.10开学第二周总结(下)(周日比赛)
- java:动态代理的使用
- 制作可在MINI2440上运行的文件系统
- angular4中关于表单的校验
- HDOJ HDU 1082 Matrix Chain Multiplication
- 125. Valid Palindrome
- html5自带表单验证-美化改造
- C# byte数组与Image的相互转换
- BZOJ1085-骑士精神(A*搜索)
- C#--反射技术