Java动态代理

会有一股神秘感。 提交于 2019-12-03 07:34:20
  1. 特点:字节码随用随创建,随用随加载。(不同于装饰模式)

  2. 作用:不修改源码的基础上对方法增强

  3. 分类:

    1. 基于接口的动态代理
    2. 基于子类的动态代理
  4. 基于接口的动态代理:

    1. 涉及的类:Proxy;提供者:JDK官方
    2. 如何创建代理对象:使用Proxy类中的newProxyInstance方法
    3. 创建代理对象的要求:被代理类最少实现一个接口,如果没有则不能使用
    4. newProxyInstance方法的参数:
      1. ClassLoader :它是用于加载代理对象字节码的,和被代理对象使用相同的类加载器
      2. Class<?>[] :它是用于让代理对象和被代理对象有相同方法
      3. InvocationHandler :它是让我们写如何代理,我们一般都是写一个该接口的实现类,通常情况下都是使用匿名内部类,此接口的实现类都是谁用谁写。
    5. 最主要的是去实现InvocationHandler 中的invoke方法。
        public static void main(String[] args)
        {
            final Producer producer = new Producer();
    
            IProducer iProducer = (IProducer) Proxy.newProxyInstance(Producer.class.getClassLoader(), Producer.class.getInterfaces(), new InvocationHandler()
            {
                /**
                 * 作用:执行被代理对象的任何接口方法都会经过该方法
                 * @param proxy     代理对象的引用
                 * @param method    当前执行的方法
                 * @param args      当前执行方法所需要的参数
                 * @return 和被代理对象方法有相同的返回值
                 * @throws Throwable
                 */
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
                {
                    Object returnValue = null;
                    // 1.获取方法执行的参数
                    Float money = (Float) args[0];
                    // 2.判断当前方法是不是销售
                    if ("saleProduct".equals(method.getName()))
                    {
                        System.out.println("代理商获取0.2的利润");
                        returnValue = method.invoke(producer, money * 0.8f);
                    }
                    return returnValue;
                }
            });
    
            iProducer.saleProduct(1000f);
        }
  5. 基于子类的动态代理
    1. 导入jar包:cglib
    2. 涉及的类:Enhancer,提供商:第三方cglib库
    3. 如何创建代理对象:使用Enhancer类中create方法
    4. 创建代理类的要求:被代理类不能是最终类
    5. create方法的参数:
      1. Class:它是用于加载代理对象字节码的,和被代理对象使用相同的类加载器
      2. Callback:它是让我们写如何代理,我们一般都是写一个该接口的实现类,通常情况下都是使用匿名内部类。我们一般写该接口的子接口实现类:MethodInterceptor
        public static void main(String[] args)
        {
            final Producer producer = new Producer();
    
            Producer proxyProducer = (Producer) Enhancer.create(producer.getClass(), new MethodInterceptor()
            {
                /**
                 * 执行被代理对象方法都会经过该方法
                 * @param proxy
                 * @param method
                 * @param args
                 *      以上三个参数和基于接口实现动态代理一样
                 * @param methodProxy   当前执行方法的代理对象
                 * @return
                 * @throws Throwable
                 */
                public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable
                {
                    Object returnValue = null;
                    // 1.获取方法执行的参数
                    Float money = (Float) args[0];
                    // 2.判断当前方法是不是销售
                    if ("saleProduct".equals(method.getName()))
                    {
                        System.out.println("代理商获取0.2的利润");
                        returnValue = method.invoke(producer, money * 0.8f);
                    }
                    return returnValue;
                }
            });
    
            proxyProducer.saleProduct(1000f);
        }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!