`

Proxy模式

阅读更多
代理模式(Proxy Pattern)

    代理模式是常用的Java 设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。

随着Proxy的流行,Sun把它纳入到JDK1.3实现了Java的动态代理。动态代理和普通的代理模式的区别,就是动态代理中的代理类是由 java.lang.reflect.Proxy类在运行期时根据接口定义,采用Java反射功能动态生成的。和 java.lang.reflect.InvocationHandler结合,可以加强现有类的方法实现。如图2,图中的自定义Handler实现 InvocationHandler接口,自定义Handler实例化时,将实现类传入自定义Handler对象。自定义Handler需要实现 invoke方法,该方法可以使用Java反射调用实现类的实现的方法,同时当然可以实现其他功能,例如在调用实现类方法前后加入Log。而Proxy类根据Handler和需要代理的接口动态生成一个接口实现类的对象。当用户调用这个动态生成的实现类时,实际上是调用了自定义Handler的 invoke方法。


1.Proxy模式
代理模式支持将某些操作从实际的对象中分离出来,通过它的代理类提供处理。这样便于修改和管理这些特定的操作。
下面示例一个代理模式的实现。
<!--[if !vml]-->
<!--[endif]-->
<<interface>>Subject.java
package com.zj.proxy;
 
public interface Subject {
    void operation1();
    
    void operation2(String arg);
} 


现实类RealSubject.java
package com.zj.proxy;
 
public class RealSubject implements Subject {
 
    public void operation1() {
       System.out.println("Realer do operation1");
    }
 
    public void operation2(String arg) {
       System.out.println("Realer do operation2 with " + arg);
    }
} 


代理类ProxySubject.java
package com.zj.proxy;
 
public class ProxySubject implements Subject {
    private Subject proxied;// 被代理对象
 
    public ProxySubject(Subject proxied) {
       this.proxied = proxied;
    }
 
    public void operation1() {
       System.out.println("Proxyer do operation1");
       proxied.operation1();
    }
 
    public void operation2(String arg) {
       System.out.println("Proxyer do operation2 with " + arg);
       proxied.operation2(arg);
    }
} 
测试类SimpleProxyDemo.java
package com.zj.proxy.client;
 
import com.zj.proxy.Subject;
import com.zj.proxy.RealSubject;
import com.zj.proxy.ProxySubject;
 
public class SimpleProxyDemo {
    public static void consumer(Subject subject) {
       subject.operation1();
       subject.operation2("ZJ");
    }
 
    public static void main(String[] args) {
       RealSubject real = new RealSubject();
       System.out.println("===Without Proxy===");
       consumer(real);
       System.out.println("===Use Proxy===");
       consumer(new ProxySubject(real));
    }
} 


结果:
引用
===Without Proxy===
Realer do operation1
Realer do operation2 with ZJ
===Use Proxy===
Proxyer do operation1
Realer do operation1
Proxyer do operation2 with ZJ
Realer do operation2 with ZJ


2.使用Java的动态代理机制
设计一个类用于实现InvocationHandle接口,InvocationHandler 是代理实例的调用处理程序实现的接口。
每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法。

<<interface>>InvocationHandle.java
package java.lang.reflect;
 
public interface InvocationHandler {
    public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable;
} 
对应invoke参数:
[1]proxy - 在其上调用方法的代理实例;
[2]method - 对应于在代理实例上调用的接口方法的 Method 实例;
[3]args - 包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为 null。
现在设计一个类实现该接口,并提供代理实例。
DynamicProxyHandler.java
package com.zj.proxy.dynamic;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
 
public class DynamicProxyHandler implements InvocationHandler {
    private Object proxied;
 
    public DynamicProxyHandler(Object proxied) {
       this.proxied = proxied;
    }
 
    public Object invoke(Object proxy, Method method, Object[] args)
           throws Throwable {
       System.out.println("**** proxy: ****\n" + proxy.getClass()
              + "\nmethod: " + method + "\nargs: " + args);
       if (args != null)
           for (Object arg : args)
              System.out.println("  " + arg);
       return method.invoke(proxied, args);
    }
} 
这里的private Object proxied;即代理实例,也即上文代理模式中介绍的RealSubject对象。
在invoke()方法中,我们会打印它的所有参数,并调用当前代理的方法。
测试类DynamicProxyDemo.java
package com.zj.proxy.client;
 
import java.lang.reflect.Proxy;
import com.zj.proxy.Subject;
import com.zj.proxy.RealSubject;
import com.zj.proxy.dynamic.DynamicProxyHandler;
 
public class DynamicProxyDemo {
    public static void consumer(Subject subject) {
       subject.operation1();
       subject.operation2("ZJ");
    }
    
    public static void main(String[] args) {
        RealSubject real = new RealSubject();
       System.out.println("===Without Proxy===");
       consumer(real);
       System.out.println("===Use Proxy===");
       Subject proxy = (Subject) Proxy.newProxyInstance(Subject.class
              .getClassLoader(), new Class[] { Subject.class },
              new DynamicProxyHandler(real));
       consumer(proxy);
    }
} 
这里通过Proxy的静态方法newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h)生成代理类,并传递与其关联的调用处理程序new DynamicProxyHandler(real)。
对于newProxyInstance()的参数:
[1]loader - 定义代理类的类加载器 ;
[2]interfaces - 代理类要实现的接口列表 ;
[3]h - 指派方法调用的调用处理程序 。
测试结果:
引用
===Without Proxy===
Realer do operation1
Realer do operation2 with ZJ
===Use Proxy===
**** proxy: ****
class $Proxy0
method: public abstract void com.zj.proxy.Subject.operation1()
args: null
Realer do operation1
**** proxy: ****
class $Proxy0
method: public abstract void com.zj.proxy.Subject.operation2(java.lang.String)
args: [Ljava.lang.Object;@de6f34
  ZJ
Realer do operation2 with ZJ
从结果可以发现,通过代理可以得到当前被调用的方法,及其参数。代理过程可以基于此进行逻辑处理,测试程序只是简单的打印这些相关信息。
本文出自 “子 孑” 博客,请务必保留此出处http://zhangjunhd.blog.51cto.com/113473/69996

本文出自 51CTO.COM技术博客
分享到:
评论

相关推荐

    Proxy 模式学习代码

    Proxy模式是一种设计模式,它允许我们为一个对象创建一个代理对象,这个代理对象在客户端和目标对象之间起到中介的作用。这种模式在软件工程中广泛应用,主要用于控制对真实对象的访问,提供额外的功能,如日志、...

    简单工厂模式,工厂方法模式,抽象工厂模式和Proxy模式

    到工厂方法到抽象工厂,这几种都带有“工厂”的模式,总是容易叫人迷糊,我仔细研究了下,然后用简单的例子做类比,列出了自己的通俗理解和比较,大部分是自己的体会,感觉理的比较清楚,末尾提了下Proxy模式。

    基于Proxy模式的分布式MySQL数据库中间件设计源码

    MySQL数据库中间件:基于C语言开发,包含59个文件,包括22个C源文件...该项目是一个分布式MySQL数据库中间件,采用Proxy模式设计,基于核心业务对象切分,旨在提供高效的数据库查询和处理能力,适用于分布式系统环境。

    从房屋买卖看 java proxy 模式

    标题中的“从房屋买卖看 java proxy 模式”暗示了我们将通过一个具体的场景来探讨 Java 中的代理(Proxy)模式。在软件设计中,代理模式是一种结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问。在...

    C++ Proxy模式

    Proxy模式是软件设计模式中的一个关键元素,属于结构型模式的一种。在C++中,Proxy模式主要用于为其他对象提供一种代理以控制对这个对象的访问。这种模式的核心思想是通过创建一个代理对象来充当目标对象的中介,...

    设计模式C++学习之代理模式(Proxy)

    代理模式是一种设计模式,它是结构型模式之一,主要用于在客户端和目标对象之间建立一个代理对象,以便控制对目标对象的访问。在C++中,代理模式可以用来为其他对象提供一种代理以控制对这个对象的访问,或者增加...

    设计模式之代理模式proxy.zip

    JDK动态代理基于接口实现,它要求目标对象必须实现至少一个接口,然后通过Proxy类和InvocationHandler接口来创建并控制代理对象。当我们调用代理对象的方法时,实际执行的是InvocationHandler的invoke方法,这样可以...

    Proxy代理模式经典实例(绝对OOP)

    在Java中,Proxy模式主要依赖于Java的动态代理机制,这通常涉及到`java.lang.reflect.Proxy`和`java.lang.reflect.InvocationHandler`两个核心接口。`Proxy`类用于生成代理对象,而`InvocationHandler`接口定义了...

    apache+tomcat负载均衡_proxy模式

    内附完整配置教程和修改后的apache的httpd.conf文件和tomcat的server.xml配置文件,包含test测试项目,不包含apache和tomcat安装文件。 本教程参考网上资料,本机测试成功,如有问题可以私信说明。

    详解设计模式中的proxy代理模式及在Java程序中的实现

    Proxy模式是设计模式中的一种,它提供了一种对对象访问的控制手段,使得在不修改原有对象的基础上,可以通过代理对象来扩展或增强原有对象的功能。在Java编程中,Proxy模式的应用非常广泛,尤其是在处理远程调用、...

    Programming_Proxy_classic_code_delphi.rar_delphi Proxy_proxy_pro

    Proxy模式是一种设计模式,其主要目的是为其他对象提供一个代理以控制对这个对象的访问。在Delphi中,Proxy可以用于创建远程代理,使得客户端可以像操作本地对象一样操作远程服务。这种模式在分布式系统、数据访问...

    23种设计模式整理pdf

    Proxy 模式是一种结构型模式,用于提供一种访问对象的接口。Proxy 模式的优点是可以提供一种统一的访问对象的接口,减少了代码的耦合度。Proxy 模式的缺点是它可能会增加代码的复杂度。 7. Adapter 模式 Adapter ...

    二十三种设计模式【PDF版】

    设计模式之 Proxy(代理) 以 Jive 为例,剖析代理模式在用户级别授权机制上的应用 设计模式之 Facade(门面?) 可扩展的使用 JDBC针对不同的数据库编程,Facade提供了一种灵活的实现. 设计模式之 Composite(组合) ...

    设计模式1,FACADE模式,Adapter

    本文将深入探讨FACADE模式、Adapter模式以及Singleton和Proxy模式的基本概念、应用场景和关键要素。 首先,FACADE(外观)模式是一种接口型模式,它的主要作用是为复杂的子系统提供一个简单的接口,使得客户端无需...

    JavaScript设计模式与开发实践.pdf

    由浅入深地讲解了16个设计模式,包括 singleton模式、Factory模式、Abstract Factory模式、Builder模式、Prototype模式、Adapter模式、Bridge模式、Composite模式、Decorator模式、Flyweight模式、Proxy模式、Chain ...

    java实现Proxy例子

    我自己用eclipse写的java代码,可以直接用eclipse导入,也可以直接用java -jar proxy_sample.jar执行 代码量很小,尽量通过注释进行说明 本例实现了InvocationHandler...在研究代理模式(Proxy模式)的朋友可以交流一下

    设计模式的几个简单例子

    Proxy模式是一种行为型设计模式,它为其他对象提供一种代理以控制对这个对象的访问。在提供的代码中,`ICar`接口定义了`MoveCar()`方法,它是所有汽车类需要遵循的行为规范。`ProxyCar`类是代理,实现了`ICar`接口,...

    设计模式原理与应用之结构型模式.pptx

    例如,远程对象访问、数据库连接池等场景都广泛使用了Proxy模式。 这些设计模式在软件开发中起着关键作用,它们提供了解决常见问题的标准方案,提高了代码的可读性、可维护性和可扩展性。理解并熟练运用这些模式,...

Global site tag (gtag.js) - Google Analytics