from://http://www.cnblogs.com/xwdreamer/archive/2012/05/23/2515306.html

设计模式之代理模式之二(Proxy)

 

0.前言

在前面一篇博客设计模式之代理模式(Proxy)中我们已经讲解了一部分代理模式,下面我们继续讲解代理的有关内容,包括代理的分类以及java中的代理。

1.代理的分类

  事实上代理能够被分为很多种类,大致有如下这些:虚代理、远程代理、copy-on-write代理、保护代理、Cache代理、防火墙代理、同步代理、智能指引。在这里我们会介绍虚代理和保护代理。

  在设计模式之代理模式(Proxy)中提到的代理就是一个典型的虚代理的实现。起初每个代理对象只有用户编号和姓名数据,直到需要的时候,才会把整个用户的数据装载到内存中来。也就是说,要根据需要来装载整个UserModel的数据,虽然用户数据对象时前面已经创建好了的,但是只有用户编号和姓名的数据,可以看成是一个“虚”的对象,知道通过代理把所有的数据都设置好,才算是一个完整的用户数据对象。

  保护代理是一种控制对原始对象访问的代理,多用于对象应该有不同的访问权限的时候。保护代理会检查调用者是否具有请求所必需的访问权限,如果没有相应的权限,那么就不会调用目标对象,从而实现对目标对象的保护。

2.java中的代理

2.1静态代理

  通常把前面自己实现的代理模式成为Java的静态代理。这种实现方式有一个较大的缺点,就是如果Subject接口发生变化,那么代理类和具体的目标实现类都要变化,不是很灵活。而使用Java内建的对代理模式支持的功能来实现则不需要修改代理类。静态代理的代码实例如下所示:

(1)创建Subject接口

public interface Subject {
public String say(String name,int age);
}

(2)创建具体的目标实现类RealSubject

package edu.sjtu.erplab.proxy3;

public class RealSubject implements Subject {
@Override
public String say(String name, int age) {
// TODO Auto-generated method stub
return "姓名:"+name+",年龄:"+age;
}
}

(3)创建代理类Proxy,代理类中有具体目标实现类的引用

package edu.sjtu.erplab.proxy3;

public class Proxy implements Subject {
private RealSubject realSubject=null;
public Proxy(RealSubject realSubject)
{
this.realSubject=realSubject;
} @Override
public String say(String name, int age) {
//在转调具体的目标对象之前,可以执行一些功能处理,比如权限判断 //转调具体的目标对象
return realSubject.say(name, age); //在转调具体的目标对象之后,可以执行一些功能处理
//这也是代理模式的核心
}
}

(4)创建客户端测试代理模式

package edu.sjtu.erplab.proxy3;

public class Client {

    public static void main(String[] args) {
// TODO Auto-generated method stub
Subject sub=new Proxy(new RealSubject());
String info=sub.say("xuwei", 25);
System.out.println(info);
}
}

2.2动态代理

  通常把使用Java内建的对代理模式支持的功能来实现的代理成为动态代理。动态代理跟静态代理相比,明显的变化是:静态代理实现的时候,在Subject接口上定义很多的方法,代理类里面自然也要实现很多方法;而动态代理的时候,在Subject接口上定义了许多方法,但是动态代理类始终只有一个invoke方法和对象绑定方法。这样,当Subject接口发生变化的时候,动态代理的接口就不需要跟着变化了。

  Java的动态代理只能代理接口,基本的实现是依靠Java的反射机制动态生成class的技术,来动态生成被代理的接口的实现对象。动态代理的代码实例如下。

第(1)步和第(2)步同上述2.1中的静态代理。这里不再赘述。

(3)定义一个实现InvocationHandler接口的动态代理类MyInvocationHandler,以完成代理的具体操作

package edu.sjtu.erplab.dynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays; public class MyInvocationHandler implements InvocationHandler { private Object obj;//代理中含有具体实现类的引用
public Object bind(Object obj) {//绑定具体实现类
this.obj = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj
.getClass().getInterfaces(), this);//获取代理对象
} @Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {//动态调用方法 System.out.println(proxy.getClass());//class $Proxy0
System.out.println(method.getName());//say
System.out.println(Arrays.toString(args));//[xuwei, 25] Object temp=method.invoke(this.obj, args);//调用方法,传入具体对象和参数
return temp;//返回方法的返回信息。
}
}

(4)创建客户端测试代理模式

package edu.sjtu.erplab.dynamicproxy;

public class DynamicProxyDemo {

    public static void main(String[] args) {
//实例化代理操作类
MyInvocationHandler hander=new MyInvocationHandler();
//绑定实际对象
Subject sub=(Subject) hander.bind(new RealSubject());
String info=sub.say("xuwei", 25);
System.out.println(info);
}
}

输出结构

class $Proxy0
say
[xuwei, 25]
姓名:xuwei,年龄:25

设计模式之代理模式之二(Proxy)的更多相关文章

  1. Java设计模式:代理模式(二)

    承接上文 三.计数代理 计数代理的应用场景是:当客户程序需要在调用服务提供者对象的方法之前或之后执行日志或者计数等额外功能时,就可以用到技术代理模式.计数代理模式并不是把额外操作的代码直接添加到原服务 ...

  2. C#设计模式之代理模式(二)

    15.3 代理模式应用实例 下面通过一个应用实例来进一步学习和理解代理模式.        1. 实例说明        某软件公司承接了某信息咨询公司的收费商务信息查询系统的开发任务,该系统的基本需 ...

  3. C#设计模式(13)——代理模式(Proxy Pattern)

    一.引言 在软件开发过程中,有些对象有时候会由于网络或其他的障碍,以至于不能够或者不能直接访问到这些对象,如果直接访问对象给系统带来不必要的复杂性,这时候可以在客户端和目标对象之间增加一层中间层,让代 ...

  4. C#设计模式:代理模式(Proxy Pattern)

    一,什么是C#设计模式? 代理模式(Proxy Pattern):为其他对象提供一种代理以控制对这个对象的访问 二,代码如下: using System; using System.Collectio ...

  5. 乐在其中设计模式(C#) - 代理模式(Proxy Pattern)

    原文:乐在其中设计模式(C#) - 代理模式(Proxy Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 代理模式(Proxy Pattern) 作者:webabcd 介绍 为 ...

  6. C#设计模式(13)——代理模式(Proxy Pattern)(转)

    一.引言 在软件开发过程中,有些对象有时候会由于网络或其他的障碍,以至于不能够或者不能直接访问到这些对象,如果直接访问对象给系统带来不必要的复杂性,这时候可以在客户端和目标对象之间增加一层中间层,让代 ...

  7. 设计模式 - 代理模式(Proxy Pattern)

    一.引言 在软件开发过程中,有些对象有时候会由于网络或其他的障碍,以至于不能够或者不能直接访问到这些对象,如果直接访问对象给系统带来不必要的复杂性,这时候可以在客户端和目标对象之间增加一层中间层,让代 ...

  8. 夜话JAVA设计模式之代理模式(Proxy)

    代理模式定义:为另一个对象提供一个替身或者占位符以控制对这个对象的访问.---<Head First 设计模式> 代理模式换句话说就是给某一个对象创建一个代理对象,由这个代理对象控制对原对 ...

  9. Java设计模式之代理模式(静态代理和JDK、CGLib动态代理)以及应用场景

    我做了个例子 ,需要可以下载源码:代理模式 1.前言: Spring 的AOP 面向切面编程,是通过动态代理实现的, 由两部分组成:(a) 如果有接口的话 通过 JDK 接口级别的代理 (b) 如果没 ...

随机推荐

  1. 洛谷P2613有理数取余

    传送门 #include <iostream> #include <cstdio> #include <cstring> #include <algorith ...

  2. Laravel Model 的 fillable (白名单)与 guarded (黑名单)

    例如 protected $fillable = ['name']; protected $guarded = ['price']; 定义了 name 字段可以写入/修改,而 price 字段不可以. ...

  3. /dev/null和/dev/zero的区别

    /dev/null,外号叫无底洞,你可以向它输出任何数据,它通吃,并且不会撑着!/dev/zero,是一个输入设备,你可你用它来初始化文件. /dev/null------它是空设备,也称为位桶(bi ...

  4. **CI中创建你自己的类库

    http://codeigniter.org.cn/user_guide/general/creating_libraries.html 创建类库 当我们使用术语"类库"时,我们一 ...

  5. Gearman In Action

    分布式任务系统是一个常见的需求,如果将 Gearman 作为 build block 来搭建这个系统的话,这样能够 make your life much easier. 首先看看 Gearman 是 ...

  6. 【LOJ】#2078. 「JSOI2016」无界单词

    题解 用所有的方案减去有界的方案 我们规定两个前缀后缀相同时长度最短的,设长度为l,因为长度最短所以他们也是无界单词,可以递推 \(f[i] = \sum_{j = 1}^{\lfloor \frac ...

  7. 记在VMware虚拟机中对网站进行性能压力测试的经历

    由于本次测试,仅仅是对静态网站首页进行的测试,所以没有涉及到MySQL数据库的性能监测 服务器基本配置 webbench测试工具 Linux上一款优秀的web性能压力测试工具.webbench最多可以 ...

  8. ubuntu16耳机没声音解决

    装完ubuntu16后又装了英伟达的显卡驱动,安装了网易云音乐后,突然发现电脑没声音,使用了如下方法解决 首先用在终端输入如下命令,下载pulseaudio音量控制软件 sudo apt instal ...

  9. conda设置Python虚拟环境

    conda设置Python虚拟环境     版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/Co_zy/article/details/7741261 ...

  10. python常用库安装网址

    python常用库安装网址如下: http://pypi.python.org/pypi