首页 > 其他 > 详细

动态代理(基于接口)

时间:2019-11-21 16:25:12      阅读:96      评论:0      收藏:0      [点我收藏+]
  1. 特点:字节码随用随创建,随用随加载

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

  3. 分类:

    1. 基于接口的动态代理

    2. 基于类的动态代理

  4. 基于接口的动态代理:

    1. 涉及 的类:Proxy

    2. 提供者:jdk

    3. 如何创建代理对象:使用Proxy类中的newProxyInstance方法

    4. 创建代理对象的要求:被代理的类最少实现一个接口,如果没有则不能使用

    5. Proxy.newProxyInstance(), newProxyInstance方法的参数:

      1. ClassLoader :类加载器

        它是同于加载代理对象的字节码的,写的是被代理对象的类加载器。(代理谁就写谁的类加载器)

      2. Class[] : 字节码数组

        它是让代理对象和被代理对象有相同的方法

      3. InvocationHandler:用于提供增强的代码

        它是让我们写如何代理。我们一般都是些一个该接口的实现类,通常情况下都是匿名内部类,但不是必须的。此接口的实现类谁用谁写

        package com.xuefei.proxy;
        
        //生产商的接口
        public interface IProducer {
            public void saleProduct(float money);
        
            public void afterProduct(float money);
        }
        package com.xuefei.proxy;
        
        //生产商实现接口
        public class Producer implements IProducer{
            public void saleProduct(float money) {
                System.out.println("拿到钱,给你商品"+money);
            }
        
            public void afterProduct(float money) {
                System.out.println("拿到钱给你售后"+money);
            }
        }
        package com.xuefei.proxy;
        
        import java.lang.reflect.InvocationHandler;
        import java.lang.reflect.Method;
        import java.lang.reflect.Proxy;
        
        public class Client {
            public static void main(String[] args) {
        
                final Producer producer = new Producer();
                IProducer proxyProducer = (IProducer)                 Proxy.newProxyInstance(producer.getClass().getClassLoader(), producer.getClass().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;
                                //获取方法执行的参数
                                Float money = (Float)args[0];
                                //判断当前方法是不是销售
                                if("saleProduct".equals(method.getName())){
                                    returnValue = method.invoke(producer,money*0.8f);
                                }
                                return returnValue;
                            }
                        });
                proxyProducer.saleProduct(1000f);
            }
        }

        运行结果:

      4. 技术分享图片

动态代理(基于接口)

原文:https://www.cnblogs.com/lililixuefei/p/11905930.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!