博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式之代理模式之二(Proxy)
阅读量:5901 次
发布时间:2019-06-19

本文共 3504 字,大约阅读时间需要 11 分钟。

0.前言

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

1.代理的分类

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

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

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

2.java中的代理

2.1静态代理

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

(1)创建Subject接口

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

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

View Code
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,代理类中有具体目标实现类的引用

View Code
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)创建客户端测试代理模式

View Code
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,以完成代理的具体操作

View Code
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)创建客户端测试代理模式

View Code
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

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/xwdreamer/archive/2012/05/23/2515306.html

你可能感兴趣的文章
sap scriptfom 多语言翻译
查看>>
黄聪:3分钟学会sessionStorage用法
查看>>
Entity Framework 全面教程详解(转)
查看>>
Windows上Python2.7安装Scrapy过程
查看>>
Chapter 3:Code Style in Django
查看>>
挖掘数据金矿 领军协同创新 曙光荣膺“2016大数据创新应用领袖企业”称号
查看>>
Fast通道获得Win10 Mobile Build 14977更新
查看>>
《BackTrack 5 Cookbook中文版——渗透测试实用技巧荟萃》—第3章3.6节识别操作系统...
查看>>
linux系统防火墙iptables命令规则及配置的示例
查看>>
10 个顶尖的 Linux 开源人工智能工具
查看>>
Firefox 跟踪保护技术将页面加载时间减少 44%
查看>>
聚合(根)、实体、值对象精炼思考总结
查看>>
java解析虾米音乐
查看>>
rails将类常量重构到数据库对应的表中之三
查看>>
mysql 多行合并函数
查看>>
【案例】RAID卡写策略改变引发的问题
查看>>
第四十八讲:tapestry 与 淘宝kissy editor编辑器带图片上传
查看>>
Linux/Centos 重置Mysql root用户密码
查看>>
[C语言]unicode与utf-8编码转换(一)
查看>>
利用PDO导入导出数据库
查看>>