`
zzq19860626
  • 浏览: 261140 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
博客专栏
B20df9e2-fb3d-3644-9f72-c1619842f682
设计模式学习笔记
浏览量:178051
87eaf24f-812a-3463-8e65-e3197d2ad8c2
java虚拟机
浏览量:26211
社区版块
存档分类
最新评论

JAVA设计模式学习13——代理模式

阅读更多

代理(proxy)模式:指目标对象给定代理对象,并由代理对象代替真实对象控制客户端对真实对象的访问。

代理模式模式有以下角色:

抽象主题(subject)角色:声明真实主题和代理主题的共同接口。

真实主题(real subject)角色:定义代理对象需要代理的真实对象。

代理主题(proxy subject)角色:代替真实对象来控制对真实对象的访问,代理对象持有真实对象的应用,从而可以随时控制客户端对真实对象的访问。

代理模式结构类图:

代理模式在java里面很常见,在开源框架里如spring,mybatis等里面大量使用。现实生活中也很常见,比如我们访问facebook主站,常会选择一些代理,通过代理访问facebook。代理分静态代理和动态代理,java对动态代理有很好的支持,提供了InvocationHandler接口和Proxy类。

 

java API 对InvocationHandler接口和Proxy类的介绍:

 

Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。创建某一接口 Foo 的代理:

     InvocationHandler handler = new MyInvocationHandler(...);
     Class proxyClass = Proxy.getProxyClass(
         Foo.class.getClassLoader(), new Class[] { Foo.class });
     Foo f = (Foo) proxyClass.
         getConstructor(new Class[] { InvocationHandler.class }).
         newInstance(new Object[] { handler });
 

或使用以下更简单的方法:

     Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
                                          new Class[] { Foo.class },
                                          handler);
 

动态代理类(以下简称为代理类)是一个实现在创建类时在运行时指定的接口列表的类,该类具有下面描述的行为。 代理接口 是代理类实现的一个接口。 代理实例 是代理类的一个实例。 每个代理实例都有一个关联的调用处理程序 对象,它可以实现接口 InvocationHandler。通过其中一个代理接口的代理实例上的方法调用将被指派到实例的调用处理程序的 Invoke 方法,并传递代理实例、识别调用方法的 java.lang.reflect.Method 对象以及包含参数的 Object 类型的数组。调用处理程序以适当的方式处理编码的方法调用,并且它返回的结果将作为代理实例上方法调用的结果返回。InvocationHandler 是代理实例的调用处理程序 实现的接口。每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法。 

 

这里举个好理解的例子:公司项目部需要CEO签署一个文件,项目负责人会把文件交给CEO助理,助理会收文件,等到CEO回来后递CEO,CEO签署后交给助理,助理收好交给项目负责人。这个过程中项目负责人其实不知道是否真的是CEO签署的文件,有可能是助理打印的CEO的签名到文件上。这样助理就是一个代理角色,代替CEO处理事务。静态代理类图如下:

代码如下: 

Java代码 
  1. package proxy;  
  2.   
  3. /** 
  4.  
  5.  *  
  6.  
  7.  *作者:alaric 
  8.  
  9.  *时间:2013-7-24下午10:44:12 
  10.  
  11.  *描述:抽象主题 
  12.  
  13.  */  
  14.   
  15. public interface Leader {  
  16.   
  17.     public void sign();  
  18.   
  19. }  

 

Java代码 
  1. package proxy;  
  2. /** 
  3.  *  
  4.  *作者:alaric 
  5.  *时间:2013-7-24下午10:45:05 
  6.  *描述:ceo  真实主题 
  7.  */  
  8. public class CEO implements Leader {  
  9.   
  10.     @Override  
  11.     public void sign() {  
  12.         System.out.println("CEO签文件");  
  13.     }  
  14.   
  15. }  

 

Java代码 
  1. package proxy;  
  2. /** 
  3.  *  
  4.  *作者:alaric 
  5.  *时间:2013-7-24下午10:45:25 
  6.  *描述:代理主题 
  7.  */  
  8. public class Assistant implements Leader{  
  9.   
  10.     private Leader leader ;  
  11.       
  12.       
  13.     public Assistant(Leader leader) {  
  14.         super();  
  15.         this.leader = leader;  
  16.     }  
  17.   
  18.   
  19.     @Override  
  20.     public void sign() {  
  21.         System.out.println("递给领导");  
  22.         leader.sign();  
  23.         System.out.println("装入袋子,送出");  
  24.     }  
  25.       
  26.   
  27. }  

 

Java代码 
  1. package proxy;  
  2.   
  3. import java.lang.reflect.InvocationHandler;  
  4. import java.lang.reflect.Method;  
  5. import java.lang.reflect.Proxy;  
  6. /** 
  7.  *  
  8.  *作者:alaric 
  9.  *时间:2013-7-24下午10:46:04 
  10.  *描述:动态代理的Handler 
  11.  */  
  12. public class AssistantHandler implements InvocationHandler {  
  13.       
  14.     /** 
  15.      * 目标对象 
  16.      */  
  17.     private Object targetObject;    
  18.         
  19.      
  20.     /** 
  21.      *  
  22.      *作者:alaric 
  23.      *时间:2013-7-24下午10:46:59 
  24.      *描述:创建代理对象 这段也可以不在此类,也可以放在客户端里面 
  25.      */  
  26.     public Object createProxy(Object targetOjbect){    
  27.         this.targetObject = targetOjbect;    
  28.         return Proxy.newProxyInstance(targetOjbect.getClass().getClassLoader(),    
  29.                 targetOjbect.getClass().getInterfaces(), this);    
  30.     };    
  31.     
  32.    
  33.     /** 
  34.      * 此方法为必须实现的,在代理实例上处理方法调用并返回结果。在与方法关联的代理实例上调用方法时,将在调用处理程序上调用此方法。  
  35.      */  
  36.     @Override    
  37.     public Object invoke(Object proxy, Method method, Object[] args)    
  38.             throws Throwable {    
  39.         Object result = null;    
  40.         System.out.println("递给领导");  
  41.         result = method.invoke(this.targetObject, args);    
  42.         System.out.println("装入袋子,送出");  
  43.         return result;    
  44.     }    
  45.   
  46. }  

 

Java代码 
  1. package proxy;  
  2.   
  3. import java.lang.reflect.Proxy;  
  4.   
  5. /** 
  6.  *  
  7.  *作者:alaric 
  8.  *时间:2013-7-24下午10:44:37 
  9.  *描述:测试类  包括静态代理和动态代理 
  10.  */  
  11. public class Client {  
  12.   
  13.     /** 
  14.      * @param args 
  15.      */  
  16.     public static void main(String[] args) {  
  17.         //静态代理测试  
  18.         CEO ceo = new CEO();  
  19.         Leader leader1 = new Assistant(ceo);  
  20.         leader1.sign();  
  21.           
  22.         System.out.println("=========================================");  
  23.         //动态代理测试,一些三种方式都可以获得动态代理对象  
  24.         AssistantHandler ah = new AssistantHandler(ceo);  
  25.         //Leader leader2 = (Leader) ah.createProxy(new CEO());  
  26.         //leader2.sign();  
  27.       
  28.         //Leader leader3 = (Leader) Proxy.newProxyInstance(CEO.class.getClassLoader(),    
  29.         //      ceo.getClass().getInterfaces(), ah);    
  30.         //leader3.sign();  
  31.           
  32.         Leader leader4 = (Leader) Proxy.newProxyInstance(Leader.class.getClassLoader(),  
  33.                  new Class[] { Leader.class },  
  34.                  ah);  
  35.         leader4.sign();  
  36.           
  37.     }  
  38.   
  39. }  

 运行结果如下:

递给领导

CEO签文件

装入袋子,送出

=========================================

递给领导

CEO签文件

装入袋子,送出

通过上面例子和代码可以看出,动态代理显得更为灵活,实际过程中动态代理也较为常用。

 

 

 

设计模式系列目录:

  • 大小: 10.2 KB
  • 大小: 8.3 KB
6
4
分享到:
评论
7 楼 le284 2014-04-18  
一般的RPC都会用到这种模式
6 楼 zzq19860626 2013-10-05  
edr_ 写道
timer_yin 写道
再加一种
Leader leader5 = (Leader) Proxy.newProxyInstance(
CEO.class.getClassLoader(), ceo.getClass().getInterfaces(), new InvocationHandler() {

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = null;   
        System.out.println("递给领导"); 
        result = method.invoke(ceo, args);   
        System.out.println("装入袋子,送出"); 
        return result;
}
});
leader5.sign();

这个是匿名内部类的使用吗??

是的
5 楼 edr_ 2013-10-02  
timer_yin 写道
再加一种
Leader leader5 = (Leader) Proxy.newProxyInstance(
CEO.class.getClassLoader(), ceo.getClass().getInterfaces(), new InvocationHandler() {

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = null;   
        System.out.println("递给领导"); 
        result = method.invoke(ceo, args);   
        System.out.println("装入袋子,送出"); 
        return result;
}
});
leader5.sign();

这个是匿名内部类的使用吗??
4 楼 timer_yin 2013-08-05  
再加一种
Leader leader5 = (Leader) Proxy.newProxyInstance(
CEO.class.getClassLoader(), ceo.getClass().getInterfaces(), new InvocationHandler() {

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = null;   
        System.out.println("递给领导"); 
        result = method.invoke(ceo, args);   
        System.out.println("装入袋子,送出"); 
        return result;
}
});
leader5.sign();
3 楼 magicyang919 2013-07-26  
顶一个啊啊
2 楼 zzq19860626 2013-07-25  
谢谢,过奖了
1 楼 nirenli 2013-07-25  
好文

相关推荐

    Java设计模式——代理设计模式(静态代理和动态代理)

    Java设计模式——代理设计模式(静态代理和动态代理) 各种情况例子源码

    浅析Java设计模式【3】——代理.pdf

    浅析Java设计模式【3】——代理.pdf

    Java设计模式 版本2

    Java设计模式,目录:前言,UML建模技术,深入浅出UML类图,从招式与内功谈起——设计模式概述,面向对象设计原则,工厂三兄弟之简单工厂模式,工厂三兄弟之工厂方法模式,工厂三兄弟之抽象工厂模式,确保对象的唯一...

    java设计模式

    目录: 前 言 第一部分 大旗不挥,谁敢冲锋——热身篇 第1章 单一职责原则 1.1 我是“牛”类,我可以担任多职吗 1.2 绝杀技,打破你的传统思维 1.3 我单纯,所以我快乐 1.4 最佳实践 ...附录:23个设计模式

    java 设计模式 静态代理模式

    //代理模式内部引用了真实角色 public void requst() { this.preRequest(); //在真实角色操作之前所附加的操作 if(null == realsubject) { realsubject = new ReallSubject(); } realsubject.requst(); // ...

    深入浅出设计模式(中文版电子版)

    4.4.2现实中的装饰模式——相架 126 4.4.3C#实例——图书馆中的项目 127 4.4.4Java实例——自定义JButton 131 4.4.5优势和缺陷 133 4.4.6应用情景 134 4.5FacadePattern(外观模式) 134 4.5.1定义 134 4.5.2...

    深入浅出设计模式(中文版)

    4.4.2现实中的装饰模式——相架 126 4.4.3C#实例——图书馆中的项目 127 4.4.4Java实例——自定义JButton 131 4.4.5优势和缺陷 133 4.4.6应用情景 134 4.5FacadePattern(外观模式) 134 4.5.1定义 134 4.5.2...

    java和设计模式ppt教程

    java和设计模式ppt包含工厂模式、建造模式、原始模型模式、单例模式、结构模式、适配器、桥梁模式、合成模式、装饰模式、门面模式、享元模式、代理模式、行为模式、解释器模式、迭代子模式、调停者模式、备忘录模式...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷6

    综合实例——Bug管理系统 (3)设计模式样例(24个讲解样例程序) pattern/src/principle/liskovsubstitution//10.3.2里氏代换原则 pattern/src/creation/factorymethod //11.1工厂方法模式 pattern/src/creation/...

    design-pattern-java.pdf

    实现对象的复用——享元模式(二) 实现对象的复用——享元模式(三) 实现对象的复用——享元模式(四) 实现对象的复用——享元模式(五) 代理模式-Proxy Pattern 设计模式之代理模式(一) 设计模式之代理模式...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷8

    综合实例——Bug管理系统 (3)设计模式样例(24个讲解样例程序) pattern/src/principle/liskovsubstitution//10.3.2里氏代换原则 pattern/src/creation/factorymethod //11.1工厂方法模式 pattern/src/creation/...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷3

    pattern/src/structure/proxy //12.3代理模式 pattern/src/structure/facade //12.4外观模式 pattern/src/structure/bridge //12.5桥接模式 pattern/src/structure/composite //12.6组合模式 pattern/src/...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷1

    pattern/src/structure/proxy //12.3代理模式 pattern/src/structure/facade //12.4外观模式 pattern/src/structure/bridge //12.5桥接模式 pattern/src/structure/composite //12.6组合模式 pattern/src/...

    【白雪红叶】JAVA学习技术栈梳理思维导图.xmind

    代理模式 创建模式 抽象工厂模式 工厂方法模式 建造这模式 原型模式 单例模式 行为模式 责任链模式 命令模式 解释器模式 迭代器模式 中介者模式 备忘录模式 观察者模式 状态模式 策略模式 模板...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷9

    综合实例——Bug管理系统 (3)设计模式样例(24个讲解样例程序) pattern/src/principle/liskovsubstitution//10.3.2里氏代换原则 pattern/src/creation/factorymethod //11.1工厂方法模式 pattern/src/creation/...

    设计模式Demo

    结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷10

    综合实例——Bug管理系统 (3)设计模式样例(24个讲解样例程序) pattern/src/principle/liskovsubstitution//10.3.2里氏代换原则 pattern/src/creation/factorymethod //11.1工厂方法模式 pattern/src/creation/...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷5

    综合实例——Bug管理系统 (3)设计模式样例(24个讲解样例程序) pattern/src/principle/liskovsubstitution//10.3.2里氏代换原则 pattern/src/creation/factorymethod //11.1工厂方法模式 pattern/src/creation/...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷7

    综合实例——Bug管理系统 (3)设计模式样例(24个讲解样例程序) pattern/src/principle/liskovsubstitution//10.3.2里氏代换原则 pattern/src/creation/factorymethod //11.1工厂方法模式 pattern/src/creation/...

Global site tag (gtag.js) - Google Analytics