`
cjc19762338
  • 浏览: 61734 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

代理模式-动态代理

阅读更多

     最近在学习代理模式,看了风中叶老师的视频后,有进一步的了解。

下面,我也来说说这个代理模式,也不不明白的地方。欢迎指教:

 

    首先要了解java设计模式中,代理模式是怎样一个概念。代理模式就是为其他对象提供一种代理以达到控制对这个对象的访问。

   

    代理模式中,有三种角色:

    抽象角色:声明真实对象和代理对象的共同接口
    代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装
    真实角色:代理角色所代表的真实对象,是我们最终要引用的对象

 

    举个例子:你有一套二手房想出手,但是你不会亲自找买房人,所以你会选择一间中介,于是中介就会代替你卖出二手房。于是,买家找到中介买房,中介手上没房子的,他只是代替卖家把房子卖给买家。

   

    下面的代码,详细说明了代理过程的实现。

 

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.Vector;

/**
 * 抽象角色:声明真实对象和代理对象的共同接口
 * 代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。
   同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装
 * 真实角色:代理角色所代表的真实对象,是我们最终要引用的对象
 *  
 * 代理类一定要实现了InvocationHandler接口  
 */  
@SuppressWarnings("unchecked")
public class ProxyObject implements InvocationHandler {
	
	//对真实角色的引用
    private Object proxy_obj;   
  
    ProxyObject(Object obj){
        this.proxy_obj = obj;   
    }   
  
    public static Object factory(Object obj){
           //返回对象的类型
        Class cls = obj.getClass();     
        /**
         * newProxyInstance(...)方法返回代理类的一个实例,返回后的代理类可以当作被代理类使用
         * 在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些 interface。
         * 这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作
         */
        return Proxy.newProxyInstance(cls.getClassLoader()/*类加载器?具体作用是?*/, cls.getInterfaces(),new ProxyObject(obj));   
    } 
    
    public void pre () {
    	System.out.println("函数调用前需要做的事情");   
    }
    
    public void post () {
    	System.out.println("函数调用后需要做的事情");   
    }
  
/**  
*实现InvocationHandler接口的invoke  
*第一个参数obj是指代理类(一般用不上),method是被代理的方法,args为该方法的参数数组。 这个抽象方法在代理类中动态实现
*/  
    public Object invoke(Object obj, Method method, Object[] args) throws Throwable {   
    	pre();
        if(args != null){   
            System.out.println("方法有  " + args.length + "    个参数");   
            for(int i = 0; i < args.length; i ++){   
                System.out.println(args[i]);   
            }   
        }
        //利用反射机制动态调用原对象的方法   
         Object mo = method.invoke(proxy_obj, args);   
         
         post ();
        return mo;   
    }   
    
    /**
     * 抽象主题角色 抽象主题角色的实例 = (抽象主题角色)factory(new 真实主题角色()); 
     * @param agr
     */
	public static void main(String agr[]){
		
		List<String> list = (List<String>) factory(new Vector<String>(10));

		list.add("mysupa.com");
		list.add("超级经纪人网");
		System.out.println(list);
    }   
}

 

动态代理步骤:(风中叶老师整理)

1.创建一个实现接口InvocationHandler的类,它必须实现invoke方法
2.创建被代理的类以及接口
3.通过Proxy的静态方法
newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) 创建一个代理
4.通过代理调用方法
 

 

 欢迎讨论!! 

分享到:
评论
19 楼 joknm 2010-10-14  
wt8414 写道
冇心人 写道
XTU_xiaoxin 写道
JavaEye上有批比较贱的人,建议楼主把自己的心得什么的记载自己的doc里面,别在javaeye上发。

JavaEye上有些垃圾装2的喜欢给别人得帖子投新手贴、隐藏贴什么的,建议楼主在javaeye上只看贴,没必要发帖,免得javaeye上这些垃圾在那装比,自己一篇帖写不出,就会装,整天给别人帖子滥投票

楼上的说的很对...我非常赞同.

+1


+1
18 楼 yanyan_zhl 2010-10-14  
咳,不要说的那么悲剧啊。新手良好又有什么呢?
新手写的谁然不是多深,但更容易上那些新手上手...
17 楼 pengzhoushuo 2010-09-08  
前段时间有一些贴,新手跟良好几乎是一样多的,最后还是新手战胜了良好。建议javaEye要改革了,再不然,大多数人真的是只看博客专栏,不看贴了。
16 楼 malixxx 2010-09-08  
管的真 妈 逼 多,以为自己是谁了,操
15 楼 pcchips 2010-08-27  
借机炒作的
14 楼 wa20463165 2010-08-26  
反正我是对设计模式不清楚,看的挺带劲!谢谢lz了
13 楼 goldendays 2010-08-26  
jammyjaccy 写道
XTU_xiaoxin 写道
只要他花了时间、花了心思写的帖子,不管内容怎样,都不应该给他投什么新手帖、隐藏贴什么的。
也许你觉得是很简单的东西,但对其他人来说也许有帮助呢,你能保证je上所有人都是高手?
   看到这帖子的投票我很生气,我一看楼主的帖子,至少是认真写的,也经过了他自己的精心排版,何必打击别人的热情呢?

同意楼上的,有些人真2,比上不足,比下有余的时候就装装,真牛逼,你自己发东西,出书,牛逼起来也行啊!这个凭什么不让别人发东西了。

12 楼 jammyjaccy 2010-08-09  
XTU_xiaoxin 写道
只要他花了时间、花了心思写的帖子,不管内容怎样,都不应该给他投什么新手帖、隐藏贴什么的。
也许你觉得是很简单的东西,但对其他人来说也许有帮助呢,你能保证je上所有人都是高手?
   看到这帖子的投票我很生气,我一看楼主的帖子,至少是认真写的,也经过了他自己的精心排版,何必打击别人的热情呢?

同意楼上的,有些人真2,比上不足,比下有余的时候就装装,真牛逼,你自己发东西,出书,牛逼起来也行啊!这个凭什么不让别人发东西了。
11 楼 XTU_xiaoxin 2010-08-09  
只要他花了时间、花了心思写的帖子,不管内容怎样,都不应该给他投什么新手帖、隐藏贴什么的。
也许你觉得是很简单的东西,但对其他人来说也许有帮助呢,你能保证je上所有人都是高手?
   看到这帖子的投票我很生气,我一看楼主的帖子,至少是认真写的,也经过了他自己的精心排版,何必打击别人的热情呢?
10 楼 czxiyj 2010-08-09  
应该给予尊重吧,我觉得楼主总结的经验也不错啊?
内容可能不深,但毕竟在分享!
9 楼 rainsilence 2010-08-09  
lz和1F的代码都看了。
我这篇博文可以说是
lz思想的加强版
http://rainsilence.iteye.com/blog/684265

to lz
将pre,post独立出去会更好

to 1f
同意把factory方法独立出去,但是不同意你把它改成非静态。
8 楼 wt8414 2010-08-09  
冇心人 写道
XTU_xiaoxin 写道
JavaEye上有批比较贱的人,建议楼主把自己的心得什么的记载自己的doc里面,别在javaeye上发。

JavaEye上有些垃圾装2的喜欢给别人得帖子投新手贴、隐藏贴什么的,建议楼主在javaeye上只看贴,没必要发帖,免得javaeye上这些垃圾在那装比,自己一篇帖写不出,就会装,整天给别人帖子滥投票

楼上的说的很对...我非常赞同.

+1
7 楼 bluemusic 2010-08-09  
非常同意啊,有些非但写不出而且看都不看就投了新手隐藏帖,完全滥用自己的大脑做出比S11还要多2的举动
6 楼 冇心人 2010-08-08  
XTU_xiaoxin 写道
JavaEye上有批比较贱的人,建议楼主把自己的心得什么的记载自己的doc里面,别在javaeye上发。

JavaEye上有些垃圾装2的喜欢给别人得帖子投新手贴、隐藏贴什么的,建议楼主在javaeye上只看贴,没必要发帖,免得javaeye上这些垃圾在那装比,自己一篇帖写不出,就会装,整天给别人帖子滥投票

楼上的说的很对...我非常赞同.
5 楼 XTU_xiaoxin 2010-08-08  
JavaEye上有批比较贱的人,建议楼主把自己的心得什么的记载自己的doc里面,别在javaeye上发。

JavaEye上有些垃圾装2的喜欢给别人得帖子投新手贴、隐藏贴什么的,建议楼主在javaeye上只看贴,没必要发帖,免得javaeye上这些垃圾在那装比,自己一篇帖写不出,就会装,整天给别人帖子滥投票
4 楼 tllyf 2010-08-07  
基础东西回顾下  有新的体会
3 楼 kevin_wanwei 2010-08-06  
管理员这里既然会有这样的贴子!!!!!!!!!!!!!
2 楼 kevin_wanwei 2010-08-06  
楼主,是干嘛的啊
1 楼 congdepeng 2010-08-06  
楼主的代码混在一起,看起来更加confused 我改写了一下啊



1.定义一个工厂,其实本质上就是利用这个方法Proxy.newProxyInstance() 产生一个Proxy实例,
package depeng.dynamicProxy;
import java.lang.reflect.Proxy;
public class ProxyFactory {
    Object factory(Object obj){
        Class cls = obj.getClass();
        return Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), new InvocationHandlerObject(obj));
    }
}



2.为什么要代理?就是让代理调用我们额外的方法,注意这个词语“调用”,就是invoke -- invocation
以前要代理,我们需要做2件事
a.构造一个代理
b.实现代理应该调用的方法

现在(a)不需要我们做了,Proxy.newProxyInstance()会帮我们做
我们只要做(b),也就是实现一个接口InvocationHandler,让这个新的代理去调用

package depeng.dynamicProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class InvocationHandlerObject implements InvocationHandler {
    Object acturyObj;

    InvocationHandlerObject(Object o) {
        acturyObj = o;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("InvocationHandlerObject.invoke()..............<in>......... ");
        pre();
        if (args != null) {
            System.out.println(" args.length " + args.length + "    ");
            for (int i = 0; i < args.length; i++) {
                System.out.println(args[i]);
            }
        }
        //这里,有几个对象/类的关系要搞清楚
        //acturyObj 是被代理的对象
        //proxy     是动态生成的代理对象
        //InvocationHandlerObject 是被proxy对象调用的,同时它有调用 acturyObj
        // proxy --> InvocationHandlerObject --> acturyObj
        System.out.println("Action method " + method.getName());
        System.out.println("acturyObj" + acturyObj.getClass());
        System.out.println("proxy" + proxy.getClass());

        Object mo = method.invoke(acturyObj, args);
        post();
        System.out.println("InvocationHandlerObject.invoke()..............<out>......... ");
        return mo;
    }

    public void pre() {
        System.out.println("InvocationHandlerObject.pre()");
    }

    public void post() {
        System.out.println("InvocationHandlerObject.post()");
    }

}


3.下面的客户端就很容易写了

package depeng.dynamicProxy;

import java.util.List;
import java.util.Vector;

public class Client {
    public static void main(String[] args) {
        List list=(List) new ProxyFactory().factory(new Vector(10));
        list.add("add method in list 1");
    }
}

相关推荐

    代理模式-静态动态代理-jdk动态代理-cglib动态代理

    在Java中,代理模式有多种实现方式,包括静态代理、JDK动态代理和CGLIB动态代理。 **静态代理** 静态代理是最早也是最基础的代理实现方式。在静态代理中,我们需要创建一个代理类,这个代理类与原始类(被代理类)...

    Java中的代理模式--静态代理和动态代理

    Java中的代理模式--静态代理和动态代理 Java中的代理模式--静态代理和动态代理

    JAVA动态代理模式-.pdf

    JAVA动态代理模式-.pdf

    代理模式与动态代理--Spring AOP原理.doc

    代理模式与动态代理--Spring AOP原理.doc

    设计模式专题之(六)代理模式---设计模式代理模式示例代码(python--c++)

    代理模式是一种常用的设计模式,它在软件开发中扮演着重要角色,主要用来为其他对象提供一种代理以控制对这个对象的访问。在这个专题中,我们将深入探讨代理模式,并通过Python和C++两种语言来实现示例代码。 首先...

    代理模式-分布式计算

    这份文件讲诉了代理模式-分布式计算,是以例子的形式进行讲诉的,希望可以帮助学习的人!

    优秀的设计模式示例-动态代理模式

    动态代理模式是一种在运行时创建代理对象以控制或扩展原有对象行为的设计模式。它允许我们为现有的对象提供一种代理以增强其功能,而无需修改原对象的代码。动态代理模式通常用于实现对目标对象的额外操作,如日志...

    设计模式-代理模式-java

    在Java中,代理模式可以通过多种方式实现,包括静态代理、动态代理(JDK动态代理和CGLIB动态代理)等。 **静态代理** 静态代理是最基础的代理形式,需要手动创建一个代理类,该类继承或实现与目标类相同的接口,并...

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

    在Java中,代理模式主要有静态代理和动态代理两种实现方式。 1. 静态代理:在编译时就已经确定了代理类与目标类的关系。通常,代理类会实现和目标类相同的接口,以便于在代理类中调用目标类的方法。这种方式的缺点...

    设计模式--代理模式

    代理模式是一种常用的设计模式,它在软件开发中扮演着重要角色,允许我们通过一个代理类来控制对原对象的访问。在《设计模式:可复用面向对象软件的基础》(通常称为GoF设计模式)中,代理模式被定义为“为其他对象...

    动态代理设计模式-源码

    动态代理设计模式是一种在运行时创建对象代理的技术,它允许我们为现有的对象提供额外的功能,而无需修改原对象的代码。这种模式的核心是接口和代理类,通过接口,代理类可以与原对象进行通信,同时在代理类中添加...

    JAVA-设计模式-结构型模式-代理模式

    JAVA-设计模式-结构型模式-代理模式

    java模式设计-代理模式之动态代理.ppt

    在Java中,动态代理是代理模式的一种实现方式,它允许我们在运行时创建代理对象,这种方式比静态代理更加灵活。动态代理在JDK 1.3及以后的版本中得到了支持,主要涉及到三个核心类:`Proxy`、`InvocationHandler`和`...

    《C++20设计模式》学习笔记-第12章代理模式-配套代码

    《C++20设计模式》学习笔记-第12章代理模式-配套代码

    设计模式-代理模式

    代理模式是一种常用的设计模式,它在软件开发中扮演着重要的角色,特别是在iOS平台的应用程序设计中。代理模式的核心思想是为一个对象提供一个替身或代理,以控制对这个对象的访问。这种模式允许我们通过代理来间接...

    Java变成模式-代理模式

    Java编程模式-代理模式。介绍了静态代理模式和动态代理模式

    java常用设计模式-代理模式

    代理模式又分为静态代理、jdk 动态代理、cglib 动态代理三种实现方式。每种实现方式都有其优点和适用的场景: 1. 静态代理:代理类需要非常明确,所以无法做到通用,但是效率也是最高的。静态代理需要定义一个接口...

    2 代理模式-MOOC课程内容.pdf

    代理模式是软件设计中的一种行为型模式,属于结构型模式的范畴。它是为了控制对一个对象的访问,从而提供一个代理或者占位符来代替原始对象。该模式的主要目的是为其他对象提供一种代理以控制对这个对象的访问。 ...

    设计模式-代理模式(讲解及其实现代码)

    设计模式-代理模式(讲解及其实现代码)

Global site tag (gtag.js) - Google Analytics