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

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】——代理 #### 一、代理模式概述 代理模式是一种行为型设计模式,主要用于在客户端与目标对象之间起到一个中介的作用,通过代理对象来控制对目标对象的访问。代理模式的核心在于它可以...

    Java设计模式源代码——自己看pdf写的

    以上只是部分Java设计模式的介绍,实际的“DesignPatterns”压缩包可能包含了这些模式的源代码实现,通过阅读和学习这些代码,开发者可以更好地理解和运用设计模式,提升代码质量。同时,结合博主提供的博客链接,...

    《java设计模式》课后习题模拟试题解答——刘伟.zip

    本资料“《java设计模式》课后习题模拟试题解答——刘伟.zip”主要涵盖了Java设计模式的学习与应用,特别是针对刘伟教授的相关课程的课后习题及模拟试题的解答。 设计模式分为三大类:创建型、结构型和行为型模式。...

    设计模式实现——代理模式

    **设计模式实现——代理模式** 在软件工程中,设计模式是一种通用可重用的解决方案,它描述了在特定上下文中经常出现的问题以及该问题的解决方案。代理模式是设计模式的一种,它提供了一种对目标对象的间接访问方式...

    java23种设计模式——图解——附带源码

    以上两种创建型模式,即工厂方法模式和抽象工厂模式,是Java设计模式中非常重要的一部分,它们可以帮助开发者更好地管理对象的创建过程,提高系统的灵活性和可扩展性。接下来的部分将继续探讨其他的设计模式。

    《Java设计模式》刘伟 课后习题及模拟试题答案.rar

    《Java设计模式》是刘伟老师的一本经典教材,它深入浅出地讲解了软件设计中的重要概念——设计模式。设计模式是经验丰富的开发者在解决常见问题时总结出的通用解决方案,是软件开发中的智慧结晶。这本书的课后习题和...

    基于Java的设计模式-代理模式demo的实现(高分课设)

    基于Java的设计模式——代理模式demo的实现(高分课设)个人经导师指导并认可通过的98分大作业设计项目,适用人群:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业或毕业设计,作为“参考资料”使用...

    设计模式——代理模式

    此外,代理模式还可以利用动态代理技术,例如Java中的`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口,这使得在运行时动态创建代理对象成为可能,而无需预先知道所有可能的代理类。...

    JAVA设计模式(代理模式)

    **Java设计模式——代理模式详解** 代理模式是软件设计模式中的一个重要组成部分,它在Java编程中扮演着举足轻重的角色。代理模式的核心思想是为一个对象提供一个替身,这个替身即代理对象,代理对象可以控制对原...

    设计模式-Java语言中的应用(pdf)

    通过深入学习《设计模式——Java语言中的应用》,开发者能够更好地理解和应用这些模式,从而编写出更加高效、可扩展的Java程序。无论是初级开发者还是经验丰富的程序员,都应该不断探索和实践设计模式,以提升自己的...

    JAVA 设计模式 工厂模式 代理模式 迭代模式 责任链模式 源码

    以下是关于JAVA设计模式中提及的四种模式——工厂模式、代理模式、迭代器模式以及责任链模式的详细说明。 1. **工厂模式**:工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。在工厂模式中,当创建...

    Java与模式——源码

    《Java与模式——源码》这个主题涉及到的是Java编程语言中的设计模式应用,以及如何通过源代码来理解和学习这些模式。设计模式是软件工程中的一种最佳实践,它们是解决常见问题的经验总结,使得代码更易读、易维护、...

    java设计模式经典教程

    ### Java设计模式经典教程知识点概览 #### 一、设计模式概述 设计模式是一种软件设计方法,它为软件开发者提供了一种标准化的方式去解决常见的软件设计问题。设计模式的使用可以提高代码的可读性和可维护性,同时...

    java设计模式

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

    java 设计模式幽默解读

    "大牛解读Java设计模式.pdf"这本书籍,作为这个主题的载体,很可能是由资深专家撰写,用生动的语言和实例帮助读者理解抽象的设计概念,从而提升他们的编程技能。无论你是初学者还是有经验的开发者,都能从中受益匪浅...

    java 设计模式 静态代理模式

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

Global site tag (gtag.js) - Google Analytics