Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / Java 代理模式应用

代理模式是一种效率非常高的模式,其定义如下:提供一种代理以控制对这个对象的访问。

代理模式也叫委托模式,它是一项基本设计技巧。许多其他的设计模式,如状态模式,策略模式,访问者模式本质上是在更特殊的场合上采用了委托模式,代理模式在日常的使用中能够提供更好的访问控制。

1: 抽象角色

抽象主题角色类可以是一个接口,是一个普通的业务类型定义,无特殊要求。


2:具体角色

也叫被委托角色,这个角色才是真正干活的角色,是业务逻辑的具体执行者


3:代理主题角色


也叫做委托类,代理类,它负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实角色实现,并且在真实主题角色处理完毕前后做预处理和善后工作。--------------------------------------分割线 --------------------------------------编写高质量代码 改善Java程序的151个建议 PDF高清完整版 http://www.linuxidc.com/Linux/2014-06/103388.htmJava 8简明教程 http://www.linuxidc.com/Linux/2014-03/98754.htmJava对象初始化顺序的简单验证 http://www.linuxidc.com/Linux/2014-02/96220.htmJava对象值传递和对象传递的总结 http://www.linuxidc.com/Linux/2012-12/76692.htmJava对象序列化ObjectOutputStream和ObjectInputStream示例 http://www.linuxidc.com/Linux/2012-08/68360.htm--------------------------------------分割线 --------------------------------------定义一个接口: package com.zzu.proxy;public interface Movable {
   void run();
} 实现类package com.zzu.proxy;public class Tank implements Movable{ @Override
 public void run() {
       
       try {
         System.out.println("Tank is running.....");
   Thread.sleep(2000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }}代理类package com.zzu.proxy;public class TankLogProxy implements Movable{ public TankLogProxy(Movable t) {
  super();
  this.t = t;
 }
 Movable t; @Override
 public void run() {
  System.out.println("start log...");
         t.run();   
        System.out.println("end log....");
 }
   
}另外一个代理类package com.zzu.proxy;public class TankTimeProxy implements Movable{ public TankTimeProxy(Movable t) {
  super();
  this.t = t;
 }
 Movable t; @Override
 public void run() {
  System.out.println("time start...");
  long start = System.currentTimeMillis();
         t.run();   
        long end = System.currentTimeMillis();
        System.out.println("time: "+(end - start));
 }
   
}client类package com.zzu.proxy;public class Client {
   public static void main(String[] args) {
  Movable m = new Tank();
  TankLogProxy tlp =  new TankLogProxy(m);
  TankTimeProxy ttp = new TankTimeProxy(tlp);
  Movable b = ttp;
  b.run();
 }
}其实代理真正有意思的地方还是在于动态代理。下面说说动态代理的内在原理 动态代理:它和普通代理的不同地方在于,他在实现阶段不用关心代理谁,而是在运行阶段来指定哪一个对象。它的实现实际上是通过JDK提供的 InvocationHandler,下面我们通过代码的形式来研究一下动态代理的内在执行机制我们先定义一个接口:package dynamic;public interface Subject {
 // 业务操作
 public void doSomething(String str);
 //增加一个方法
 public void doGirl();
}接口的实现package dynamic;public class RealSubject implements Subject { @Override
 public void doSomething(String str) {
  System.out.println("do some things -->>> " + str);
 } @Override
 public void doGirl() {
        System.out.println("to find a girl --->>>>> "); 
 }}动态代理的handler类package dynamic;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
 * 其中的InvocationHandler是JDK提供的动态代理的接口,其中的invoke方法是InvocationHandler必须实现的,它完成对真实方法的调用,即所有的真实方法调用都交给handler来接管
 * @author Administrator
 *
 */
public class MyInvocationHandler implements InvocationHandler {
 // 被代理的对象
 private Object target = null; // 通过构造函数传递一个对象 public MyInvocationHandler(Object _obj) {
  this.target = _obj;
 } @Override
 public Object invoke(Object proxy, Method method, Object[] args)
   throws Throwable {
  return method.invoke(this.target, args);
 }}动态代理类package dynamic;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;public class DynamicProxy<T> {
 public static <T> T newProxyInstance(ClassLoader loader,
   Class<?>[] interfaces, InvocationHandler h) {
  // 寻找joinPoint连接点,AOP框架使用元数据定义
  if (true) {
   // 执行前一个通知
   new BeforeAdvice().exec();
  }
  return (T) Proxy.newProxyInstance(loader, interfaces, h); }
}动态代理的场景类package dynamic;import java.lang.reflect.InvocationHandler;public class Client { /**
  * @param args
  */
 public static void main(String[] args) {
       //定义一个主题
  Subject subject = new RealSubject();
  //定义一个handler
  InvocationHandler handler = new MyInvocationHandler(subject);
  //定义主题的代理
  Subject proxy = DynamicProxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), handler);
  //代理的行为,
  proxy.doSomething("Finish");
  proxy.doGirl();
 }}动态代理实际上个人感觉和普通代理没什么区别,实际上的作用就是在不改变代码的情况下增强或控制对象的行为,
 
动态代理实现代理的职责,业务逻辑实现相关的逻辑功能,两者之间没有必然的相互耦合的关系。本文永久更新链接地址:http://www.linuxidc.com/Linux/2014-07/104327.htm