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);

 

posted @ 2019-05-28 12:36  MrChengs  阅读(156)  评论(0编辑  收藏  举报