0 0

java中为什么要给类使用代理?它有哪些好处?5

Spring中什么时候用cglib代理,什么时候用java动态代理
2009年4月20日 23:54

5个答案 按时间排序 按投票排序

0 0

采纳的答案

代理模式

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

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

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

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

真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。(参见文献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, J2EEjava语言JDK1.4APIjavalangObject.html">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类)也可以动态改变,从而实现了非常灵活的动态代理关系

2009年4月21日 03:48
0 0

spring中代理接口的时候用java动态代理
代理具体类的时候要用到cglib

2009年4月21日 09:55
0 0

看看这文章

http://www.iteye.com/topic/182654

2009年4月21日 09:49
0 0

Spring 中常常使用Proxy,是为了在真实目标类上,加入一些其它操作,而这些操作的细节都交给代理处理,你只需要集中目标类功能的实现。

2009年4月21日 00:26
0 0

代理的作用太广了。。。
日常的,如使用代理上网。
在jive 论坛程序大量使用Proxy,它封装了权限,缓存等,当使用某个类,都是返回它的Proxy类,如使用ForumManager,它会返回一个ForumManager的Proxy,加入了一些其它控制因素。
在Jmock中同样是创建一个Proxy,模拟真实对象。
在Spring中,提供了多种代理,利用jdk中api,需要提供接口。而cglib是不需要的,可以直接创建类的Proxy。

2009年4月21日 00:22

相关推荐

    java动态代理详细解析

    在学习之前,先提出几个问题,带着问题来看代码: 1.什么是动态代理? 2.为什么使用动态代理? 3.使用它有哪些好处? 4.哪些地方需要动态代理?

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

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

    java动态代理实现与原理详细分析.docx

     代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理...

    java面试题

    对比之下forward更加高效,并且它有助于隐藏实际地址,但是有些情况则必须使用redirect,否则会报异常。 jsp中动态include和静态include的区别? 答:动态include用jsp:include实现,适用于动态页面,可以携带参数 ...

    java面试800题

    Q0058 一个Java抽象类声明了一个方法并会抛出一个异常,问继承这个抽象类的子类,实现了这个方法,这个方法声明是不是一定要抛出一模一样的异常,可不可以不抛,或者抛出的异常比抽象类的异常范围大,或者小?...

    Spring面试题含答案.pdf

    2. 使用 Spring 框架的好处是什么? 3. Spring 由哪些模块组成? 4. 核心容器(应用上下文) 模块 5. BeanFactory – BeanFactory 实现举例 6. XMLBeanFactory 7. 解释 AOP 模块 8. 解释 JDBC 抽象和 DAO 模块 9. ...

    Java.lang.Instrument 代理Agent使用

    在 类的字节码载入JVM前 会调用ClassFileTransformer的transform方法,从而实现修改原类方法的功能,实现AOP,这个的好处是 不会像动态代理或者CGLIB技术实现AOP那样会产生一个新类,也不需要原类要有接口 。...

    # 动态代理的应用场.md

    动态代理是一种常见的设计模式,它在Java开发中广泛应用。通过动态代理,我们可以在运行时生成代理类,用于代理真实对象的方法调用。这种代理机制允许我们在不修改原始代码的情况下,对原始对象的行为进行扩展、增强...

    java设计模式选择题复习题.doc

    工厂系列模式的优缺点: 让用户的代码和某个特定类的子类的代码解耦 用户不必知道它所使用的对象是怎样创建的,只需知道该对象有哪些方法 抽象工厂模式可以为用户创建一系列相关的对象,使用户和创建这些对象的类脱...

    java餐饮系统源码-jade-proxiedhttps:NGinx反向代理背后的JADE/强化HTTPSMTP

    为什么要使用它,有什么好处? Java 中没有密码学:更快、更安全,没有 Java KeyStores 独立于 JADE/Java 开放接收端口:关注点分离,使用不同的 Unix 用户 在传入位命中 Java [TCP、TLS、HTTP、HTTP 方法(仅 POST...

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

    设计模式之 Template(模板方法) 实际上向你介绍了为什么要使用 Java 抽象类,该模式原理简单,使用很普遍. 设计模式之 Strategy(策略) 不同算法各自封装,用户端可随意挑选需要的算法. 设计模式之 Chain of ...

    java代码自动生成源码-AutoInterface:自动生成Java接口源代码

    为类或接口生成Decorator接口 好处 只有一个实现时,无需手动维护接口 帮助诸如Spring之类的框架进行依赖注入 Spring运行时注入默认情况下需要一个Interface,否则spring使用CGLIB代理。 通过自动生成接口,您不需要...

    Jenny:JNI胶水代码生成器

    (java类的c ++端代理。) 还有一个额外的好处使用C ++ RAII技术来简化JNI API。 当选择在(与'jenny.useJniHelper'=true ),生成的代理类也将使用add方法jnihelper ,这让生活更快乐!为什么选择珍妮? 在编写JNI...

    Hibernate中文API

    所有的持久化类(persistent classes)都要求有无参的构造器,因为Hibernate必须使用Java反射机制来为你创建对象。构造器(constructor)的访问级别可以是private,然而当生成运行时代理(runtime proxy)的时候则...

    新版Android开发教程.rar

    � A ndroid 在设计初期就考虑了与现其有业务的融合,改变以往从计算机为主改成从手机使用为导向。新 生应用如:G oogle 地图及其衍生应用、 GMail 、 GTalk 等。 � GPS 卫星导航功能,手机照相, MP3 ,蓝芽等均...

    ssh(structs,spring,hibernate)框架中的上传下载

     使用BlobByteArrayType字段类型后,为什么我们就可以象一般的字段类型一样操作Blob字段呢?可以确定的一点是:BlobByteArrayType不可能逾越Blob天生的操作方式,原来是BlobByteArrayType数据类型本身具体数据访问...

    1579068285.png

    1、代理类继承了Proxy类并且实现了要代理的接口,由于java不支持多继承,所以JDK动态代理不能代理类 2、重写了equals、hashCode、toString 3、有一个静态代码块,通过反射或者代理类的所有方法 4、通过...

    网络安全的关键技术有哪些.doc

    网络安全的关键技术有哪些? 一.虚拟网技术 虚拟网技术主要基于近年发展的局域网交换技术(ATM和以太网交换)。交换技术 将传 统的基于广播的局域网技术发展为面向连接的技术。因此,网管系统有能力限制局域网 通讯 ...

    java 常用设计模式(2)

    —————————— 代理模式(Proxy) ——————————- ...  –>只是在代理类中,实例化原类,在原类方法的前后添加新的逻辑。  如下: 抽象角色: abstract public class Subject { abstract

    毕业设计-基于JAVA的系统框架设计与开发(源代码+论文)

    在业务层则是采用单例模式设计与Spring的IoC模式相结合,实现了公共代理类的编写,各业务逻辑接口的封装。而在持久层的设计中则是采用基于现有持久层框架的实现模式,实现了对产生Session实例的封装,对常用数据库...

Global site tag (gtag.js) - Google Analytics