动态代理

动态代理:

    原理:使用一个代理将对象包装起来,然后用该对象取代原始对象,任何对原始对象的调用都要通过代理,代理对象决定是否以及何时讲方法调用转到原始对象上

动态代理:

   1. 基于接口   -----JDK动态代理

   2.基于继承    -----CGlib动态代理

 

 

   类似微商,微商就是代理,他宣传买东西,你通过他买东西,但是真正买东西的还是卖家:

   比如程序代码计算器,如果想增减日志代理、验证代理等,但是计算实现功能依然是【程序代码计算器】

//接口,目标类和代理类都实现同一个接口

public
interface ArithmeticCalculator { int add(int a,int b); int sub(int a,int b); int mul(int a,int b); int div(int a,int b); }

 

public class ArithmeticCalculatorImpl implements ArithmeticCalculator {
    @Override
    public int add(int a, int b) {
        int result = a + b;
        return result;
    }

    @Override
    public int sub(int a, int b) {
        int result = a - b;
        return result;
    }

    @Override
    public int mul(int a, int b) {
        int result = a * b;
        return result;
    }

    @Override
    public int div(int a, int b) {
        int result = a / b;
        return result;
    }
}

 

 

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * JDK的动态代理
 * 1. Proxy:是所有动态类的父类,专门为用户生成代理类或者代理对象
 *        @CallerSensitive
 *        public static Class<?> getProxyClass(ClassLoader loader,
 *                                          Class<?>... interfaces)
 *        用于生成代理类的Class对象
 *        @CallerSensitive
 *        public static Object newProxyInstance(ClassLoader loader,
 *                                           Class<?>[] interfaces,
 *                                           InvocationHandler h)
 *        用于生成代理类对象
 * 2. InvocationHandler:完成动态代理的整个过程。
 *         public Object invoke(Object proxy, Method method, Object[] args)
 *         throws Throwable;
 *
 */
public class ArithmeticCalculatorProxy {
    private Object target;

    public ArithmeticCalculatorProxy(Object target) {
        this.target = target;
    }

    public Object getProxy(){
        Object proxy;
        /**
         * loader: ClassLoader对象,类加载器对象,帮我们加载动态生成的代理类
         * interfaces:接口们,提供目标对象的所有接口,目的是让代理对象与目标对象都有接口中相同的方法
         * InvocationHandler : 接口
         */
        ClassLoader classLoader = target.getClass().getClassLoader();
        Class<?>[] interfaces = target.getClass().getInterfaces();
        proxy = Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
            /**
             * invoke: 代理对象调用代理方法,会回来调用invoke方法
             * proxy:代理对象,在invoke方法中一般不会使用
             * method:正在被调用的方法对象
             * args: 正在被调用方法的参数
             */

            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                //讲方法的调用转到目标对象上
                //获取方法的名字
                String methodName = method.getName();
                //记录日志
                System.out.println(" zhe method "+methodName+" begin");
                Object result = method.invoke(target, args);
                System.out.println(" zhe method "+methodName+" end");

                return result;
            }
        });
       return proxy;
    }

}

 

 

 模拟动态代理底层实现

class $Proxy0 extends Proxy implements  ArithmeticCalculator{

    protected $Proxy0(InvocationHandler h) {
        super(h);
    }

    @Override
    public int add(int a, int b) {
        //return super.h.invoke(this,方法对象,方法参数);
        return 0;
    }

    @Override
    public int sub(int a, int b) {
        return 0;
    }

    @Override
    public int mul(int a, int b) {
        return 0;
    }

    @Override
    public int div(int a, int b) {
        return 0;
    }
}

 

 

 

public class Demo {
    public static void main(String[] args)throws Exception {
        ArithmeticCalculatorImpl arithmeticCalculator = new ArithmeticCalculatorImpl();
        Object proxy = new ArithmeticCalculatorProxy(arithmeticCalculator).getProxy();
        /**
         * 第一步 : 生成代理类,
         *          (1)  proxy = Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler()....
         *           通过这个方法生成代理对象,
         *
         * 第二步: 根据代理类生成代理对象
         *         Object proxy = new ArithmeticCalculatorProxy(arithmeticCalculator).getProxy();
         *
         * 第三步:对象调用相应方法 proxy3.add(1, 1)
         *        第三步底层模拟如下
         *         class $Proxy0 extends Proxy implements  ArithmeticCalculator{
         *
         *             protected $Proxy0(InvocationHandler h) {
         *             super(h);
         *          }
         *
         *          @Override
         *          public int add(int a, int b) {
         *                  此处会调用此方法  super.h.invoke(this,方法对象,方法参数);它会调用  Invocation接口中的invoke方法
         *                  public Object invoke(Object proxy, Method method, Object[] args)
         *                  throws Throwable;
         *             //return super.h.invoke(this,方法对象,方法参数);
         *             return 0;
         *            }
         *
         *          @Override
         *          public int sub(int a, int b) {
         *           return 0;
         *          }
         *
         *         @Override
         *         public int mul(int a, int b) {
         *           return 0;
         *         }
         *
         *         @Override
         *         public int div(int a, int b) {
         *            return 0;
         *         }
         * }
         */
        ArithmeticCalculator proxy3 =(ArithmeticCalculator)proxy;

        System.out.println(proxy3.add(1, 1));
    }
}

 

posted @ 2019-08-20 22:08  lcj12121  阅读(159)  评论(0编辑  收藏  举报