zoukankan      html  css  js  c++  java
  • 模式的秘密---代理模式

    第1章 代理模式概念介绍

    本章讲述了代理模式的分类、应用场景及作用

    第2章 常用代理模式原理

    本章介绍静态代理、动态代理实现原理。并通过案例讲解 JDK 动态代理以及使用 cglib 实现动态代理

    引入包快捷键

    打印快捷键

    继承的方式实现静态代理:调用父类的方法。

    使用聚合的方式,通过把参数传入进来,调用move方法。

     

     

    更正:第一个参数一般是指被代理类。

     创建被代理的类以及接口:被代理的类Car,被代理的接口Moveable

    cglib-nodep-2.2.2.jar 下载地址

    http://www.java2s.com/Code/Jar/c/Downloadcglibnodep213jar.htm

    package com.imooc.proxy;
    
    public interface Moveable {
        void move();
    }
     1 package com.imooc.proxy;
     2 
     3 import java.util.Random;
     4 
     5 public class Car implements Moveable {
     6 
     7     @Override
     8     public void move() {
     9         long starttime = System.currentTimeMillis();
    10         System.out.println("汽车开始行驶...");
    11         // 实现开车
    12         try {
    13             Thread.sleep(new Random().nextInt(1000));
    14             System.out.println("汽车行驶中....");
    15         } catch (InterruptedException e) {
    16             e.printStackTrace();
    17         }
    18         long endtime = System.currentTimeMillis();
    19         System.out.println("汽车结束行驶...汽车行驶时间:" + (endtime - starttime) + "毫秒!");
    20     }
    21 
    22 }
    package com.imooc.proxy;
    
    public class Client {
        /**
         * 测试类
         */
        public static void main(String[] args) {
            Car car = new Car();
            car.move();
        }
    }

    静态代理的实现

    使用继承的方式实现静态代理

    package com.imooc.proxy;
    
    public interface Moveable {
        void move();
    }
     1 package com.imooc.proxy;
     2 
     3 import java.util.Random;
     4 
     5 public class Car implements Moveable {
     6     @Override
     7     public void move() {
     8         // 实现开车
     9         try {
    10             Thread.sleep(new Random().nextInt(1000));
    11             System.out.println("汽车行驶中....");
    12         } catch (InterruptedException e) {
    13             e.printStackTrace();
    14         }
    15     }
    16 
    17 }
    package com.imooc.proxy;
    
    public class Car2 extends Car {
        @Override
        public void move() {
            long starttime = System.currentTimeMillis();
            System.out.println("汽车开始行驶...");
            super.move();//使用继承的方式实现Car2对Car的代理
            long endtime = System.currentTimeMillis();
            System.out.println("汽车结束行驶...汽车行驶时间:" + (endtime - starttime) + "毫秒!");
        }
    }
    package com.imooc.proxy;
    
    public class Client {
        /**
         * 测试类
         */
        public static void main(String[] args) {
    //        Car car = new Car();
    //        car.move();
            
            Moveable m=new Car2();
            m.move();
        }
    }

     使用聚合的方式实现静态代理

    什么是聚合?

    通过传进来的参数来调用move()方法

    package com.imooc.proxy;
    
    public interface Moveable {
        void move();
    }
    package com.imooc.proxy;
    
    import java.util.Random;
    
    public class Car implements Moveable {
        @Override
        public void move() {
            // 实现开车
            try {
                Thread.sleep(new Random().nextInt(1000));
                System.out.println("汽车行驶中....");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
    }
     1 package com.imooc.proxy;
     2 
     3 public class Car3 implements Moveable {
     4     private Car car;
     5 
     6     public Car3(Car car) {
     7         super();
     8         this.car = car;
     9     }
    10 
    11     @Override
    12     public void move() {
    13         long starttime = System.currentTimeMillis();
    14         System.out.println("汽车开始行驶...");
    15         car.move();//使用聚合的方式实现Car3对Car的代理
    16         long endtime = System.currentTimeMillis();
    17         System.out.println("汽车结束行驶...汽车行驶时间:" + (endtime - starttime) + "毫秒!");
    18 
    19     }
    20 
    21 }
     1 package com.imooc.proxy;
     2 
     3 public class Client {
     4     /**
     5      * 测试类
     6      */
     7     public static void main(String[] args) {
     8 //        Car car = new Car();
     9 //        car.move();
    10         //使用继承方式
    11 //        Moveable m=new Car2();
    12 //        m.move();
    13         //使用聚合方式实现
    14         Car car = new Car();
    15         Moveable m=new Car3(car);
    16         m.move();
    17     }
    18 }

     使用聚合的方式实现功能的叠加(对时间、日志的代理)

    package com.imooc.proxy;
    
    public interface Moveable {
        void move();
    }
     1 package com.imooc.proxy;
     2 
     3 import java.util.Random;
     4 
     5 public class Car implements Moveable {
     6     @Override
     7     public void move() {
     8         // 实现开车
     9         try {
    10             Thread.sleep(new Random().nextInt(1000));
    11             System.out.println("汽车行驶中....");
    12         } catch (InterruptedException e) {
    13             e.printStackTrace();
    14         }
    15     }
    16 
    17 }
     1 package com.imooc.proxy;
     2 //对时间的代理
     3 public class CarTimeProxy implements Moveable {
     4     private Moveable m;
     5 
     6     public CarTimeProxy(Moveable m) {
     7         super();
     8         this.m = m;
     9     }
    10 
    11     @Override
    12     public void move() {
    13         long starttime = System.currentTimeMillis();
    14         System.out.println("汽车开始行驶...");
    15         m.move();//使用聚合的方式实现Car3对Car的代理
    16         long endtime = System.currentTimeMillis();
    17         System.out.println("汽车结束行驶...汽车行驶时间:" + (endtime - starttime) + "毫秒!");
    18 
    19     }
    20 
    21 }
     1 package com.imooc.proxy;
     2 //对日志的代理
     3 public class CarLogProxy implements Moveable {
     4     private Moveable m;
     5 
     6     public CarLogProxy(Moveable m) {
     7         super();
     8         this.m = m;
     9     }
    10 
    11     @Override
    12     public void move() {
    13         System.out.println("日志开始...");
    14         m.move();
    15         System.out.println("日志结束..." );
    16 
    17     }
    18 
    19 }
     1 package com.imooc.proxy;
     2 //使用聚合的方式,代理之间可以互相传递的
     3 public class Client {
     4     /**
     5      * 测试类
     6      */
     7     public static void main(String[] args) {
     8         //创建子类对象,调用的方法为子类重写的方法或者继承的方法
     9         Car car=new Car();
    10         
    11         //先记录日志再记录时间
    12 //        CarTimeProxy ctp = new CarTimeProxy(car);
    13 //        CarLogProxy clp=new CarLogProxy(ctp);
    14 //        clp.move();
    15         
    16         //先记录时间再记录日志
    17         CarLogProxy clp=new CarLogProxy(car);
    18         CarTimeProxy ctp = new CarTimeProxy(clp);
    19         ctp.move();
    20     }
    21 }

    动态代理实现

    1.创建一个实现接口InvocationHandler的类,它必须实现invoke方法

     1 package com.imooc.jdkproxy;
     2 
     3 import java.lang.reflect.InvocationHandler;
     4 import java.lang.reflect.Method;
     5 
     6 public class TimeHandler implements InvocationHandler {
     7 
     8     private Object target;
     9 
    10     public TimeHandler(Object target) {
    11         super();
    12         this.target = target;
    13     }
    14 
    15     /**
    16      * 参数: 
    17      * proxy 被代理对象
    18      * method 被代理对象的方法 
    19      * args 方法的参数
    20      * 
    21      * 返回值:
    22      * Object 方法的返回值
    23      */
    24 
    25     @Override
    26     public Object invoke(Object proxy, Method method, Object[] args)
    27             throws Throwable {
    28         long starttime = System.currentTimeMillis();
    29         System.out.println("汽车开始行驶...");
    30         method.invoke(target);
    31         long endtime = System.currentTimeMillis();
    32         System.out.println("汽车结束行驶...汽车行驶时间:" + (endtime - starttime) + "毫秒!");
    33         return null;
    34     }
    35 
    36 }

    2.创建被代理的类以及接口

    package com.imooc.proxy;
    
    public interface Moveable {
        void move();
    }
     1 package com.imooc.proxy;
     2 
     3 import java.util.Random;
     4 
     5 public class Car implements Moveable {
     6     @Override
     7     public void move() {
     8         // 实现开车
     9         try {
    10             Thread.sleep(new Random().nextInt(1000));
    11             System.out.println("汽车行驶中....");
    12         } catch (InterruptedException e) {
    13             e.printStackTrace();
    14         }
    15     }
    16 
    17 }

    3.调用Proxy的静态方法,创建一个代理类

    4.通过代理调用方法

     1 package com.imooc.jdkproxy;
     2 
     3 import java.lang.reflect.InvocationHandler;
     4 import java.lang.reflect.Method;
     5 import java.lang.reflect.Proxy;
     6 
     7 import com.imooc.proxy.Car;
     8 import com.imooc.proxy.Moveable;
     9 
    10 public class Test {
    11 
    12     /**
    13      * JDK动态代理测试类
    14      */
    15     public static void main(String[] args) {
    16         Car car = new Car();
    17         InvocationHandler h = new TimeHandler(car);
    18         Class<?> cls = car.getClass();
    19         /**
    20          * 动态创建代理类 
    21          * loader 类加载器 
    22          * interfaces 实现接口 
    23          * h InvocationHandler 事务处理器
    24          */
    25         // Proxy.newProxyInstance(loader, interfaces, h)
    26         // 对时间的动态代理
    27         Moveable m = (Moveable) Proxy.newProxyInstance(cls.getClassLoader(),
    28                 cls.getInterfaces(), h);
    29         m.move();//相当于method.invoke(Object proxy,Object[] args)
    30                  //相当于move.invoke(m)
    31     }
    32 }

    第3章 自定义类模拟 JDK 动态代理的实现

    本章通过编写自定义类,模拟 JDK 动态代理的实现,帮助大家深入理解 JDK 动态代理的实现原理与机制

    commons-io-2.6.jar下载地址

    https://mvnrepository.com/artifact/commons-io/commons-io/2.6

    抛出异常快捷键

    ctrl+1

    第4章 代理模式总结

    总结代理模式分类、应用场景、实现原理、实现方式及实现方式优缺点

     

  • 相关阅读:
    DAY 42 前端
    DAY 41 mysql
    DAY 40 前端学习
    DAY 39 前端学习
    DAY 38 前端学习
    DAY 37 前端学习
    上传一个桌面
    找到anaconda中自带的qtdesigner,设计ui文件并生成py文件
    python课程:python3的数字与字符串
    python3 偏最小二乘法实现
  • 原文地址:https://www.cnblogs.com/songsongblue/p/9882066.html
Copyright © 2011-2022 走看看