代理模式为其他的对象增加一个代理对象,进行访问控制。从而避免直接访问一个对象,造成效率或者安全性上的降低。去掉了某些功能,或提供了某些格外的服务。
1 远程代理,为一个远程对象,创建一个本地的代理对象。每次访问,直接访问本地代理对象即可。
2 虚拟代理,如果对象很大,直接访问开销很大,可以为他创建一个代理对象,只生成关键的信息即可。
3 保护代理,(权限控制)为某个对象增加一种保护机制,只有一定的权限才能通过这个代理,访问后面的对象。
4 智能引用代理,提供目标对象一些额外的服务。
被代理类和代理类通过继承相同的接口。
1.创建Movable接口
public interface Movable { public void move(); }
2.创建被代理类,实现了Movable接口
public class Car implements Movable { @Override public void move() { try { Thread.sleep(new Random().nextInt(1000)); System.out.println("汽车行驶中……"); } catch (InterruptedException e) { e.printStackTrace(); } } }
3.创建一个时间的代理类,实现了Movable接口
public class TimeProxy implements Movable{ public TimeProxy(Movable m) { super(); this.m = m; } private Movable m; @Override public void move() { long startTime = System.currentTimeMillis(); System.out.println("汽车开始行驶"); m.move(); long endTime = System.currentTimeMillis(); System.out.println("汽车开始行驶,行驶时间为:"+(endTime-startTime)+"毫秒"); } }
4.如果存在多个代理类,如一个日志的代理类
public class LoggerProxy implements Movable{ public LoggerProxy(Movable m) { super(); this.m = m; } private Movable m; @Override public void move() { System.out.println("开始记录日志"); m.move(); System.out.println("记录日志结束"); } }
5.客户端调用
public class Client { public static void main(String[] args) { Car car = new Car(); TimeProxy time = new TimeProxy(car); LoggerProxy log = new LoggerProxy(time); log.move(); } }
6.结果显示
1、省略静态代理的1,2步骤。即已经有了movable接口和car类
2、创建时间代理,并且继承了 InvocationHandler 接口,实现了invoke()方法。在invoke()方法的前后增加业务逻辑。
public interface InvocationHandler{ Object invoke(Object proxy, Method method, Object[] args) throws Throwable; }
1. proxy
就是通过 Proxy.newProxyInstance()
方法创建的动态代理类,它实现了指定的interfaces接口。 通常这个对象在invoke函数中不使用。
2. Method
表示动态代理类所实现的接口中的方法。通过 Method
对象可以获取方法名、参数类型、返回类型等信息。
3. Object[] args
包含了传入动态代理类所实现的方法的参数值。
public class TimeProxy implements InvocationHandler { public TimeProxy(Object target) { super(); this.target = target; } Object target; /**参数: * proxy:被代理的对象 * method:被代理的方法 * arg:方法的参数 * 返回object对象 */ @Override public Object invoke(Object proxy, Method method, Object[] arg) throws Throwable { long startTime = System.currentTimeMillis(); System.out.println("汽车开始行驶"); method.invoke(target); long endTime = System.currentTimeMillis(); System.out.println("汽车行驶结束,行驶时间为:"+(endTime-startTime)+"毫秒"); return null; }
3.客户调用,用到Proxy类中的newProxyInstance()方法,使用Proxy.newProxyInstance()
方法创建动态代理类,方法定义:
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
ClassLoader
:加载动态代理类的类加载器InvocationHandler
:事件处理,转发所有的方法调用代理。public class Client { public static void main(String[] args) { Car car = new Car(); Class<?>cls = car.getClass(); TimeProxy handle = new TimeProxy(car); /* * 参数分别为 */ Movable m = (Movable) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(),handle); m.move(); } }
4.运行结果为
1.引用cglib-nodep-2.1_3 jar包
2.创建一个类,如Car
public class Car { public void move(){ System.out.println("汽车行驶中……"); } }
3.创建一个cglib代理。通过获得动态代理,拦截所有目标类方法的调用
public class CglibProxy implements MethodInterceptor { private Enhancer enhancer = new Enhancer(); //获得动态代理 public Object getProxy(Class cls){ enhancer.setSuperclass(cls); enhancer.setCallback(this); return enhancer.create(); } //拦截所有目标类方法的调用 @Override public Object intercept(Object obj, Method method, Object[] arg, MethodProxy proxy) throws Throwable { //添加业务逻辑 System.out.println("开始记录日志"); proxy.invokeSuper(obj, arg); System.out.println("记录日志结束"); return null; } }
4.Client客户端
public class Client{ public static void main(String[] args) { CglibProxy proxy = new CglibProxy(); Car car = (Car) proxy.getProxy(Car.class); car.move(); } }
5.运行结果
具体原理待完善……因为我还没有完全搞明白!
原文:http://www.cnblogs.com/doudingbest/p/4963249.html