第1章 代理模式概念介绍
本章讲述了代理模式的分类、应用场景及作用
第2章 常用代理模式原理
本章介绍静态代理、动态代理实现原理。并通过案例讲解 JDK 动态代理以及使用 cglib 实现动态代理
引入包快捷键
打印快捷键
继承的方式实现静态代理:调用父类的方法。
使用聚合的方式,通过把参数传入进来,调用move方法。
更正:第一个参数一般是指被代理类。
创建被代理的类以及接口:被代理的类Car,被代理的接口Moveable
cglib-nodep-2.2.2.jar 下载地址
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 @Override12 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 @Override12 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 @Override12 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 @Override26 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下载地址
抛出异常快捷键
ctrl+1
第4章 代理模式总结
总结代理模式分类、应用场景、实现原理、实现方式及实现方式优缺点