模式的秘密---代理模式
第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章 代理模式总结
总结代理模式分类、应用场景、实现原理、实现方式及实现方式优缺点