• jdk动态代理


    上次给大家举了个例子 QQ 车的例子  QQ车装饰者模式加强QQ车的功能的方法 在不破坏原有对象的的基础上进行加强,

    那么我们现在又想给QQ车 加强一些功能呢?  按照装饰者模式的思想 我们又得去写一个qqWrepper类增加功能,如果有

    几十个上百个功能需要加强呢?我们就要写好几十个类 代码量太多。

         有没有一种方式 能让我们获取到一个被加强的对象 而且又不需要写qqwrepper类 。 有 ,就是今天要引入的动态代理。

    不用写qqwrepper,直接返回一个被加强的对象。

     

    jdk动态代理 必须要有接口

    看看jdk代理如何在不需要写装饰类的前提下 直接返回一个被加强的对象。

    在java的反射包下有一个proxy类

    查阅api文档

          object obj= proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)

        JDK 中提供了这个方法 帮你创建一个实例对象,要求你传入三个参数,不需要写类  直接返回一个加强对象 

        第一个传入对象参数 ClassLoader:类加载器  因为它要帮你直接返回一个已被增强的对象,必须有一个对应的类加载在内存中的,

                         这里本应该传入的是一个 加强过对象的类加载器,但是一般传入的被加强对象的类加载器。

                  interfaces    传入的是增强对象的接口列表  保证被加强对象和加强对象的声明保持保持一致。

                  InvocationHandler  执行处理类 接口  传参数的时候一定是一个对象。InvaocationHandler接口的实现类对象

        

      InvocationHandler接口中只有一个方法 invoke 方法

          

      invoke(Object proxy, Method method, Object[] args)

        proxy:指的是即将被返回的已经被加强过的对象。

        Method:指的是执行的方法。

        args: 方法执行的参数列表  

        上代码看看:

    public class Demo {
        public static void main(String[] args) throws Exception {
            final QQ qq = new QQ();
            //使用动态代理 增强它
            Car zengqian = (Car) Proxy.newProxyInstance(qq.getClass().getClassLoader(),qq.getClass().getInterfaces(), new InvocationHandler() {
                        @Override                                            
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                                 proxy 代表即将返回的代理对象 
                            String name = method.getName();

          
                            if("run".equals(name)){  

            加强你想增加的方法  其他方法不需要增强 就执行原来的方法 


                                long start = System.currentTimeMillis();  qq 车加速之前的时间

              
                                Object invoke = method.invoke(qq);  原有对象的引用


                                long end = System.currentTimeMillis(); qq车加速之后的时间


                                System.out.println(end-start);


                                return invoke;
                            }else{
                                 method.invoke(qq,args);   调用deriver 方法需要参数 传入参数。
                                 return 100;
                            }
                        }
                    });
            
            
            //zengqian.run();
            //zengqian.stop();
            //zengqian.driver("小明"); 
            int oilTank = zengqian.oilTank();
            System.out.println(oilTank);
            
            
        }
    }

      

  • 相关阅读:
    linux 首次登陆与线上求助
    003生信人必练
    计算器概论
    01 git 概念
    01 基因组学基本感念
    Python 函数习题
    Python字符编码详解,str,bytes
    python class
    [Leetcode]287. Find the Duplicate Number
    深度解析Word2vec
  • 原文地址:https://www.cnblogs.com/xiaowazi/p/9085297.html
Copyright © 2020-2023  润新知