设计模式之代理模式
- 代理模式基本概念及其分类
- 代理模式开发中应用场景
- 代理模式实现方式
- JDK动态代理实现
什么是代理模式
为其他对象提供一种代理以控制这个对象的访问。起到中介的作用,去掉一些功能服务,或者增加额外的功能服务
常见的代理模式
- 远程代理
- 虚拟代理
- 保护代理
- 智能引用代理
1.远程代理
为不同地理位置的对象提供局域网的代理对象
2. 虚拟代理
根据希求将资源消耗很大的对象进行延迟加载,到真正需要的时候进行创建
3. 保护代理
控制用户的访问权限
4. 智能引用代理
提供目标对象的一些额外服务
代理模式的实现
1. 静态代理
代理和被代理对象在代理之前是确定的。他们都实现相同的接口或者继承相同的抽象类
2. 动态代理
Java动态代理类位于java.lang.reflect包下面,一般主要涉及到以下两个类:
-
nterface InvocationHandler :该接口仅仅定义了一个方法
/** * 这个方法在动态代理类中实现 * @param object 一般是指代理类 * @param method 被代理的方法 * @param args 该方法的参数数组 * @return */ public Object invoke(Object object,Method method,Object[] args) ;
-
Proxy : 该类即动态代理类
/** * 获取代理类的实例,返回后的代理类可以当作代理类使用(可使用被代理类的在接口中声明过的方法) * * @param loader * @param interfaces * @param handler * @return */ static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler handler);
代码实现:
package proxy; import java.util.Random; /** * 基本的类,一个Car类实现了一个Moveable接口,接口中只有一个move()方法 * @author chen * */ public class Car implements Moveable { @Override public void move() { //实现开车方法 //开车 try { Thread.sleep(new Random().nextInt(1000)); System.out.println("汽车正在行驶。。。。。"); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } }
package proxy; /** * Moveable接口 * @author chen * */ public interface Moveable { /** * 移动方法 */ void move(); }
package jdkProxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** * 为被代理类的代理方法提供时间统计 * @author chen * */ public class TimeHandler implements InvocationHandler { //代理对象 private Object object; //含参构造方法 public TimeHandler(Object obj) { // TODO Auto-generated constructor stub this.object = obj; } /** * @proxy 被代理对象 * @methid 被代理方法 * @args 被代理方法的参数 * * return 返回值是该方法的返回值 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub System.out.println("开始记录时间!"); //记录开始时间 long startTime = System.currentTimeMillis(); //本次的被代理方法没有参数,故不填 method.invoke(object); //记录结束时间 long endTime = System.currentTimeMillis(); System.out.println("结束记录时间!"); System.out.println("耗费时间:" + (endTime - startTime) + " ms!"); //返回值为null return null; } }
package jdkProxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import proxy.Car; import proxy.Moveable; /** * JDK动态代理的测试类 * @author chen * */ public class Test { public static void main(String[] args) { //创建需要被代理的对象 Car car = new Car(); //获取类加载器 Class<?> cls = car.getClass(); ClassLoader loader = cls.getClassLoader(); //获取代理的是适配器 InvocationHandler h = new TimeHandler(car); Moveable m = (Moveable)Proxy.newProxyInstance(loader, cls.getInterfaces(), h); m.move(); } }