`
zhaohaolin
  • 浏览: 1024700 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

java代理模式及动态代理类

阅读更多

1.      代理模式

代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

代理模式一般涉及到的角色有:

抽象角色 :声明真实对象和代理对象的共同接口;

代理角色 :代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。

真实角色 :代理角色所代表的真实对象,是我们最终要引用的对象。(参见文献1)

以下以《 Java 与模式》中的示例为例:

抽象角色:

abstract public class Subject

{

    abstract public void request();

}

真实角色:实现了 Subject request() 方法。

public class RealSubject extends Subject

{

       public RealSubject()

       {

       }

      

       public void request()

       {

              System.out.println("From real subject.");

       }

}

代理角色:

public class ProxySubject extends Subject

{

    private RealSubject realSubject;  // 以真实角色作为代理角色的属性

      

       public ProxySubject()

       {

       }

 

       public void request()  // 该方法封装了真实对象的 request 方法

       {

        preRequest(); 

              if( realSubject == null )

        {

                     realSubject = new RealSubject();

              }

        realSubject.request();  // 此处执行真实对象的 request 方法

        postRequest();

       }

 

    private void preRequest()

    {

        //something you want to do before requesting

    }

 

    private void postRequest()

    {

        //something you want to do after requesting

    }

}

客户端调用:

Subject sub=new ProxySubject();

Sub.request();

       由以上代码可以看出,客户实际需要调用的是 RealSubject 类的 request() 方法,现在用 ProxySubject 来代理 RealSubject 类,同样达到目的,同时还封装了其他方法 (preRequest(),postRequest()) ,可以处理一些其他问题。

       另外,如果要按照上述的方法使用代理模式,那么真实角色必须是事先已经存在的,并将其作为代理对象的内部属性。但是实际使用时,一个真实角色必须对应一个代理角色,如果大量使用会导致类的急剧膨胀;此外,如果事先并不知道真实角色,该如何使用代理呢?这个问题可以通过 Java 的动态代理类来解决。

 

2. 动态代理类

       Java 动态代理类位于 Java.lang.reflect 包下,一般主要涉及到以下两个类:

(1). Interface InvocationHandler :该接口中仅定义了一个方法 Object invoke(Object obj,Method method, Object [] args) 。在实际使用时,第一个参数 obj 一般是指代理类, method 是被代理的方法,如上例中的 request() args 为该方法的参数数组。这个抽象方法在代理类中动态实现。


(2).Proxy
:该类即为动态代理类,作用类似于上例中的 ProxySubject ,其中主要包含以下内容:

Protected Proxy(InvocationHandler h) :构造函数,估计用于给内部的 h 赋值。

Static Class getProxyClass (ClassLoader loader, Class[] interfaces) :获得一个代理类,其中 loader 是类装载器, interfaces 是真实类所拥有的全部接口的数组。

Static Object newProxyInstance (ClassLoader loader, Class[] interfaces, InvocationHandler h) :返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)。


      
所谓Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些 interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然啦,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。(参见文献3)

    在使用动态代理类时,我们必须实现InvocationHandler接口,以第一节中的示例为例:

抽象角色 (之前是抽象类,此处应改为接口):

public interface Subject

{

    abstract public void request();

}

具体角色 RealSubject :同上;

 

代理角色:

import java.lang.reflect.Method;

import java.lang.reflect.InvocationHandler;

 

public class DynamicSubject implements InvocationHandler {

  private Object sub;

 

  public DynamicSubject() {

  }

 

  public DynamicSubject(Object obj) {

    sub = obj;

  }

 

 

  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

    System.out.println("before calling " + method);

 

    method.invoke(sub,args);

 

    System.out.println("after calling " + method);

    return null;

  }

 

}

 

       该代理类的内部属性为 Object 类,实际使用时通过该类的构造函数 DynamicSubject(Object obj) 对其赋值;此外,在该类还实现了 invoke 方法,该方法中的

method.invoke(sub,args);

其实就是调用被代理对象的将要被执行的方法,方法参数 sub 是实际的被代理对象, args 为执行被代理对象相应操作所需的参数。通过动态代理类,我们可以在调用之前或之后执行一些相关操作。

客户端

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Proxy;

import java.lang.reflect.Constructor;

import java.lang.reflect.Method;

 

public class Client

{

 

    static public void main(String[] args) throws Throwable

       {

      RealSubject rs = new RealSubject();  // 在这里指定被代理类

      InvocationHandler ds = new DynamicSubject(rs);  // 初始化代理类

         Class cls = rs.getClass();

      // 以下是分解步骤

      /*

       Class c = Proxy.getProxyClass(cls.getClassLoader(),cls.getInterfaces()) ;

       Constructor ct=c.getConstructor(new Class[]{InvocationHandler.class});

       Subject subject =(Subject) ct.newInstance(new Object[]{ds});

     */

     // 以下是一次性生成

      Subject subject = (Subject) Proxy.newProxyInstance(cls.getClassLoader(),

                                 cls.getInterfaces(),ds );


     
subject.request();

}

       通过这种方式,被代理的对象 (RealSubject) 可以在运行时动态改变,需要控制的接口 (Subject 接口 ) 可以在运行时改变,控制的方式 (DynamicSubject ) 也可以动态改变,从而实现了非常灵活的动态代理关系(参见文献2)。

 

 

参考文献:

1.      阎宏,《J ava 与模式》

2.          透明 , 《动态代理的前世今生》

3.   Forest Hou, Dynamic Proxy Java RMI 中的应用》



版权声明:CSDN是本Blog托管服务提供商。如本文牵涉版权问题,CSDN不承担相关责任,请版权拥有者直接与文章作者联系解决。

分享到:
评论

相关推荐

    Java代理模式Java动态代理

    ### Java代理模式与Java动态代理详解 #### 一、代理模式概述 代理模式是一种软件设计模式,它在客户端和目标对象之间提供了一种间接层。这种模式的主要目的是控制客户端对目标对象的访问,并且可以在不修改原有...

    java装饰模式及动态代理模式示例源码

    装饰模式和动态代理模式是Java编程中两种非常重要的设计模式,它们都在代码的扩展性和灵活性方面发挥着关键作用。下面将分别对这两种模式进行详细解释,并结合手写的数据库连接池和动态代理模式的使用进行深入探讨。...

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

    动态代理则是在运行时动态生成代理类,不需要提前编写代理类的代码。Java提供了一个内置的机制来实现动态代理,即`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。 1. **定义接口**:与...

    对代理模式与Java动态代理类的理解

    对代理模式与Java动态代理类的理解说明

    Java设计模式-代理模式例子

    在这个“Java设计模式-代理模式例子”中,我们可能能看到如何创建静态代理类,以及如何利用`Proxy`和`InvocationHandler`创建动态代理。源码分析可以帮助我们更好地理解代理模式的实现细节,并能将其运用到自己的...

    JAVA设计模式之代理模式实例

    在本实例中,我们将深入探讨Java中的代理模式及其应用。 代理模式的核心思想是为一个对象创建一个代理对象,这个代理对象在客户端和目标对象之间起到中介的作用。它可以控制目标对象的访问,也可以在调用目标对象的...

    用Java实现的代理模式之动态代理

    在Java中,代理模式有静态代理和动态代理两种实现方式。本篇将重点讨论"动态代理",这是一种在运行时创建代理对象的技术,使得我们可以在程序运行过程中,根据需要动态地生成具有额外功能的代理类。 动态代理主要由...

    java代理模式

    Java代理模式是一种设计模式,它在面向对象编程中扮演着重要的角色,主要目的是为了在不修改原有对象的基础上,为对象添加额外的功能或者控制对对象的访问。代理模式的核心思想是通过代理类来间接调用目标类的方法,...

    JAVA设计模式(代理模式)

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

    Java 静态代理模式

    - 可以通过代理类动态扩展功能。 **缺点**: - 需要为每个目标类创建一个代理类,如果目标类数量多,会导致代理类的数量过多。 - 代理类和目标类必须实现相同的接口,限制了使用场景。 - 代码紧密耦合,如果接口...

    java代理模式和动态代理

    ### Java代理模式和动态代理详解 #### 一、概述 在软件工程中,代理模式是一种常用的软件设计模式,主要用于在不直接暴露目标对象的情况下提供一个替代接口。这种模式可以简化客户端与目标对象之间的交互,同时还...

    java动态代理类的实例

    在Java中,静态代理是通过定义一个与被代理类实现相同接口的新类来实现的,而动态代理则在运行时动态生成此类,无需预先编写代理类的代码。 `java.lang.reflect.Proxy`类是Java动态代理的核心,它提供了创建代理...

    java静态代理、动态代理、装饰设计模式

    在Java编程中,代理模式是一种常见的设计模式,它允许我们为一个对象提供一个代理以控制对这个对象的访问。代理模式通常用于增加额外的功能或在访问原对象时进行额外的操作,比如日志记录、安全控制、性能统计等。...

    Java 动态代理详解(代理模式+静态代理+JDK动态代理+CGLIB动态代理)

    Java 动态代理详解(代理模式+静态代理+JDK动态代理+CGLIB动态代理) Java 动态代理是 Java 编程语言中的一种强大工具,广泛应用于 Spring AOP、Hibernate 数据查询、测试框架的后端 mock、RPC 远程调用、Java 注解...

    java + 动态代理 + 动态代理实际应用场景

    1:静态代理出现的实际背景,静态代理时如何演化成动态代理 2: 动态代理demo 举例实际应用场景(载入数据库驱动的时候,使用AIDL与系统Servic...4: 动态代理使用到基础理论:Class.forName("xxxx") 得到Class类 。

    代理模式java代码 Proxy(5) 2个代理类

    在这个主题“代理模式java代码 Proxy(5) 2个代理类”中,我们可以理解为将介绍两种不同的代理类实现。 1. 静态代理 在静态代理中,我们需要创建一个接口,然后让目标对象和代理对象都实现这个接口。代理类会持有...

    Java中的代理模式Demo

    在Java编程中,代理模式是一种设计模式,它允许我们在不修改原有对象的基础上,在对象周围创建一个代理对象,这个代理对象可以扩展目标对象的功能或者控制对目标对象的访问。代理模式通常用于实现动态代理、远程代理...

    JAVA静态代理和动态代理

    总结来说,Java的静态代理适用于代理类较少且代理逻辑相对固定的情况,而动态代理则在代理类数量不确定或者代理逻辑可能变化时更为合适。两者都可以实现为原始对象添加附加功能,但动态代理在灵活性和代码维护方面...

    java中的三种代理模式

    JDK动态代理基于Java反射API,可以在运行时动态地生成代理类和实例。它需要目标对象实现至少一个接口,然后通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来创建代理对象。...

    Java 代理 代理模式 静态代理与动态代理 常见的动态代理实现 .md

    ### Java 代理模式详解 #### 1. 代理模式概览 代理模式是一种设计模式,主要目的是为了控制或提供对某对象的访问。在代理模式中,代理对象充当客户端与真实对象之间的中介,使得客户端可以通过代理对象间接地访问...

Global site tag (gtag.js) - Google Analytics