博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
5、反射-动态代理
阅读量:7106 次
发布时间:2019-06-28

本文共 5436 字,大约阅读时间需要 18 分钟。

 

创建动态代理

1、Proxy提供用于创建动态代理类和代理对象的静态方法,他是所有动态代理类的父类

2、Proxy提供了两个方法来创建动态代理类和动态代理实例

 

需求

代码执行之前

代码执行之后都需要进行代码的打印

interface ArithmeticCalcular {    public int add(int a,int b);    public  int sub(int a , int b);}
public class ArithmeticCalcularImpl implements ArithmeticCalcular {    @Override    public int add(int a, int b) {        System.out.println("方法执行之前add");        int res = a + b;        System.out.println("add: " + res);        return res;    }    @Override    public int sub(int a, int b) {        System.out.println("方法执行之前sub");        int res = a -b ;        System.out.println("sub:" + res);        return res;    }}

这里会发现再方法中的代码很多都是重复的

public static void main(String[] args) {        ArithmeticCalcular add = new ArithmeticCalcularImpl();        add.add(1,2);    }

此时可以发现如果日志文件过多,很多代码会重用,而且同样的代码需要多次使用(甚至超过程序代码)

 

此时可以使用动态代理

代理设计的原理:

使用一个代理将对象包装起来

然后使用该代理对象取代原始对象

任何对象的调用都有通过代理对象

代理对象决定是否可以及时将方法调用转到原始对象上

public class ArithmeticCalcularImpl1 implements ArithmeticCalcular {    @Override    public int add(int a, int b) {        int res = a + b;        return res;    }    @Override    public int sub(int a, int b) {        int res = a -b ;        return res;    }}
/*            newProxyInstance(ClassLoader loader,Class
[] interfaces,InvocationHandler h) ClassLoader:由动态代理产生的对象由那个类加载器进行加载(通常情况下和被代理对象使用一样的类加载器) interfaces:由动态代理产生的对象必须实现的接口的Class数组 InvocationHandler:当具体调用代理对象方法时,将产生什么具体行为 */ ArithmeticCalcular arithmeticCalcular = new ArithmeticCalcularImpl1(); ArithmeticCalcular proxy = (ArithmeticCalcular) Proxy.newProxyInstance(arithmeticCalcular.getClass().getClassLoader(), new Class[]{ArithmeticCalcular.class}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("invoke.."); return 0; } }); int add = proxy.add(2, 4); System.out.println(add);

此时的返回值0就是InvocationHandler中的返回值

 

final ArithmeticCalcular arithmeticCalcular = new ArithmeticCalcularImpl1();        ArithmeticCalcular proxy =                (ArithmeticCalcular) Proxy.newProxyInstance(arithmeticCalcular.getClass().getClassLoader(),                        new Class[]{ArithmeticCalcular.class}, new InvocationHandler() {                            @Override                            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {                                //proxy:                                //method:正在被调用的方法                                //args:调用方法传入的参数                                          System.out.println("method :" + method);                                //method :public abstract int cn.com.mrchengs.proxy.ArithmeticCalcular.add(int,int)                                          System.out.println("args:" + Arrays.asList(args));                                //args:[2, 4]                                //日志前置                                          System.out.println("method before :"   + method.getName());                                //method before :add                                //调用被代理类的目标方法                                Object invoke = method.invoke(arithmeticCalcular, args);                                //日志后置                                          System.out.println("method after : " + method.getName());                                //method after : add                                          return invoke;                            }                        });        int add = proxy.add(2, 4);        System.out.println(add);

 

 

再次更新一下

ArithmeticCalcularImpl1 arithmeticCalcular = new ArithmeticCalcularImpl1();        ArithmeticCalcular proxy =                (ArithmeticCalcular) Proxy.newProxyInstance(arithmeticCalcular.getClass().getClassLoader(),                        new Class[]{
arithmeticCalcular.getClass().getInterfaces().getClass()}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //proxy: //method:正在被调用的方法 //args:调用方法传入的参数 System.out.println("method :" + method); //method :public abstract int cn.com.mrchengs.proxy.ArithmeticCalcular.add(int,int) System.out.println("args:" + Arrays.asList(args)); //args:[2, 4] //日志前置 System.out.println("method before :" + method.getName()); //method before :add //调用被代理类的目标方法 Object invoke = method.invoke(arithmeticCalcular, args); //日志后置 System.out.println("method after : " + method.getName()); //method after : add return invoke; } }); int add = proxy.add(2, 4); System.out.println(add);

 

转载于:https://www.cnblogs.com/Mrchengs/p/10936493.html

你可能感兴趣的文章
Extjs4 DateTimeField,日期时间控件完美版
查看>>
php中判断iphone版本
查看>>
C++多线程中用临界区控制全局变量的访问冲突问题
查看>>
VICA 架构设计
查看>>
Linux 搭建 Jenkins
查看>>
「热点」Service Mesh利器:NGINX将支持gRPC
查看>>
Google开源其Java容器化工具Jib,简化镜像构建全流程
查看>>
冬季取暖误区!家有老人请注意!
查看>>
跑在Kubernetes上的开源深度学习,百度这次带来了哪些技术看点?
查看>>
华为无愧行业翘楚,Mate 8等七款老机型升级EMUI 8.0
查看>>
阿里亮相 SIGCOMM2017 调度系统NetO惊艳全场
查看>>
华为云中国行2018·杭州,共享数字红利
查看>>
三星S8的18.5:9全视曲面屏,带来的不仅仅是更好的视觉体验
查看>>
蓝色金属的灵动之美:华为P10 Plus钻雕蓝惊艳眼球
查看>>
人民币对美元汇率中间价报6.7025元 上调318个基点
查看>>
“银狐”里皮现身广州白云机场返意 正式告别中国
查看>>
海南新增海口、博鳌两家市内免税店
查看>>
葡萄酒公司连续亏损多年 曾是茅台集团的“心病与包袱”
查看>>
意大利5岁华人男孩溜出家门独自上街 监护人被控
查看>>
首批45户困难青少年家庭入住公租房
查看>>