• 5、反射-动态代理


    创建动态代理

    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);
  • 相关阅读:
    Linux性能优化实战学习笔记:第十九讲
    Linux性能优化实战学习笔记:第二讲
    Docker:企业级私有仓库harbor[十六]
    Docker:跨主机容器间通信之overlay [十五]
    Docker:macvlan实现容器跨主机通信 [十四]
    Docker:容器的四种网络类型 [十三]
    Docker:单机编排工具docker-compose [十二]
    Docker:私有仓库registry [十一]
    Docker:容器间互联的应用zabbix监控项目 [十]
    Docker:dockerfile镜像的分层 [九]
  • 原文地址:https://www.cnblogs.com/Mrchengs/p/10936493.html
Copyright © 2020-2023  润新知