代理模式,以及Java的动态代理

2023-10-27

定义

为其他对象提供一种代理以控制对这个对象的访问。可以提供额外不同的操作。

UML类图

Subject类:定义了RealSubject和Proxy的共用接口,这样就在任何使用RealSubject的地方都可以使用Proxy

RealSubject类:真是实体

Proxy类:代理类,保存一个引用使得代理可以访问实体,并提供一个与Subject接口相同的接口,这样代理就可以用来替代实体。

简单的代码类如下:

public abstract class Subject {
    public abstract void Request();
}

public class RealSubject extends Subject {
    @Override public void Request() {
        System.out.println("真实请求");
    }
}

public class Proxy extends Subject {
    private RealSubject realObject = new RealSubject();
    @Override public void Request() {
        System.out.println("代理的请求");
        realObject.Request();
    }
}

public class Client {
    public static void main(String[] args) {
        Subject proxy = new Proxy();
        proxy.Request();
    }
}

示例

举个栗子,大学的时候经常在宿舍里不想出去,有时候让室友帮忙在食堂里带饭。

我:在宿舍不想出去

室友:帮我带饭

public abstract class Subject {
    public abstract void buyLaunch();
}

public class RealSubject extends Subject {
    @Override public void buyLaunch() {
        System.out.println("我要买午饭");
    }
}

public class Proxy extends Subject {
    private RealSubject realObject = new RealSubject();

    @Override public void buyLaunch() {
        System.out.println("室友帮我买午饭");
        wrapLaunch();
        realObject.buyLaunch();
    }

    private void wrapLaunch() {
        System.out.println("打包带走");
    }
}

代理模式其实就是这么简单~~~

 

Java的动态代理

接下来看一下Java提供的动态代理,动态代理比代理的思想更前进了一步,因为它可以动态地创建代理并动态地处理对所有方法的调用。在动态代理上所做的所有调用都会被重定向到单一的调用处理器上,它的工作是揭示调用的类型并确定相应的对策。

先来看一下动态代理的例子:

public interface ObjectInterface {
    void doSomething();

    void somethingElse(String arg);
}

public class RealObject implements ObjectInterface {
    @Override public void doSomething() {
        System.out.println("doSomething");
    }

    @Override public void somethingElse(String arg) {
        System.out.println("somethingElse " + arg);
    }
}
public class DynamicProxyHandler implements InvocationHandler {
    private Object proxied;

    public DynamicProxyHandler(Object proxied) {
        this.proxied = proxied;
    }

    @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Proxy: " + proxy.getClass() + ", method:" + method + ", args:" + args);
        if (args != null) {
            for (Object arg : args) {
                System.out.println("  " + arg);
            }
        }
        return method.invoke(proxied, args);
    }
}
public class SimpleDynamicProxy {

    public static void consumer(ObjectInterface iface) {
        iface.doSomething();
        iface.somethingElse("bonobo");
    }

    public static void main(String[] args) {
        RealObject real = new RealObject();
        ObjectInterface proxy = (ObjectInterface) Proxy.newProxyInstance(ObjectInterface.class.getClassLoader(),
                new Class[]{ObjectInterface.class}, new DynamicProxyHandler(real));
        consumer(proxy);
    }
}

通过调用静态方法Proxy.newProcyInstance()创建动态代理,这个方法需要得到一个类加载器,一个你希望该代理实现的接口列表,以及InvocationHandler接口的一个实现,然后返回接口类型的对象。动态代理可以将所有调用重定向到调用处理器,因此通常会向调用处理器的构造器传递给一个“实际”对象的引用,从而使得调用处理器在执行其中介任务时,可以将请求转发。

看一下SimpleDynamicProxy运行的输入内容:

在consumer方法中,调用ObjectInterface的任何方法,都会先经过DynamicProxyHandler的invoke方法中转,实现统一处理的功能。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

代理模式,以及Java的动态代理 的相关文章

随机推荐

  • rsa2加解密及签名校验

    非对称加解密 第一种用法 私钥签名 公钥验签 用于签名 第二种用法 公钥加密 私钥解密 用于加解密 class Rsa2Controller extends Controller 第一种应用 验签 私钥加密 公钥验签 return stri
  • web开发资源

    1 http www cnblogs com lhb25 archive 2011 05 26 1997341 html 主要进行web开发 2
  • 洛谷P1216 [USACO1.5][IOI1994]数字三角形 Number Triangles题解

    接触的第一道DP题 动态规划入门 题目描述 写一个程序来查找从最高点到底部任意处结束的路径 使路径经过数字的和最大 每一步可以走到左下方的点也可以到达右下方的点 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 在上面的样例中 从
  • javafx 图片加载不出来,并且文件是可导的情况

    1 检查是不是没有在new imgae 前面加上file 如果是文件的话 或者URL 如果是网址 2 可能是file 中间无意识加了空格 我就是这样怎么查都查不出来 这样的结果就是显示一片空白 没有图片 而且不报错 3 另外 注意如果批量命
  • Unity私有变量在其它脚本的获取

    Unity私有变量在其它脚本的获取 以下是脚本A private int curHealth 5 int value 2 public int Health set curHealth value get return curHealth
  • Spring学习--IOC容器的初始化过程

    IOC容器初始化概述 IOC容器初始化是由refresh 方法来启动的 这个方法标志着IOC容器的正式启动 Spring将IOC容器启动的过程分开 并使用不同的模块来完成 如使用ResourceLoader BeanDefinition等模
  • 解决:"MySQL error code 145 Table was marked as crashed and should be repaired"的问题

    该错误指的是数据库的表损坏需要修复 我的数据库客户端使用的是Navicat 通过查看服务的错误日志我们可以知道具体是哪个表出现了问题 在Navicat上如果试图鼠标双击打开那个被损坏的表也会显示如标题所示的错误信息 MySQL error
  • Ubuntu安装软件时Could not get lock /var/lib/dpkg/lock - open (11: Resource temporarily unavailable)的解决方案

    Ubuntu 19 04 在安装wireshark的时候 sudo apt get install wireshark后遇到报错如下 E Could not get lock var lib dpkg lock open 11 Resour
  • 运维基础知识

    一 简述运维流程 1 接手平台 管理资产 增删 设置平台对资产是扫描策略 2 每天按照规定的巡检周期对资产进行巡检 巡检过程中检测资产的目前状态做记录 查看是否有新增告警事件 将发现的新增告警事件按照规定输出详细的事件工单 工单内要求详细描
  • Error processing condition on org.springframework.cloud.commons.httpclient.HttpClientConfiguration

    背景 创建springboot项目后 导入nacos 配置中心和注册中心依赖后报错 springboot启动类无法正常启动 控制台异常如题 报错源码 java lang IllegalStateException Error process
  • Springboot数据库连接池报错的解决办法

    Springboot数据库连接池报错的解决办法 这个异常通常在Linux服务器上会发生 原因是Linux系统会主动断开一个长时间没有通信的连接 那么我们的问题就是 数据库连接池长时间处于间歇状态 导致Linux系统将其断开了 然后抛出了这个
  • 关于解决win10的 tencent qqmail plugin 卸载不了的问题

    问题出现场景 我也是偶然一次在搜索我电脑里面下载的程序时 发现有个叫做tencent qqmail plugin的程序怎么也删除不掉 经过的我不断的尝试 欸 我终于找到解决方法了 问题描述 我之前使用的方法的是在 设置 应用 应用程序 中卸
  • 在VMware里克隆出来的CentOSLinux。。 ifconfig...没有看到eth0.。然后重启网卡又报下面错误。

    原文地址 http www 51testing com html 90 360490 846295 html 故障现象 service network restart Shutting down loopback insterface OK
  • 流程图中的虚线含义_流程图图形符号标准含义简介

    流程图是我们工作中经常会用到的一种工具 形象直观 便于理解 直观地描述一个工作过程的具体步骤 流程图对准确了解事情是如何进行的 以及决定应如何改进过程极有帮助 这一方法可以用于整个企业 以便直观地跟踪和图解企业的运作方式 流程图中有很多图形
  • 数据挖掘初探(skleran)

    1 使用sklearn进行数据挖掘 1 1 数据挖掘的步骤 数据挖掘通常包括数据采集 数据分析 特征工程 训练模型 模型评估等步骤 我们使用sklearn进行虚线框内的工作 sklearn也可以进行文本特征提取 通过分析sklearn源码
  • RT-Thread记录(十一、I/O 设备模型之UART设备 — 源码解析)

    深入理解 RT Thread I O 设备模型 分析 UART设备源码 目录 前言 一 初识 UART 操作函数 应用程序 二 UART 的初始化 2 1 UART 设备初始化位置 2 2 UART 设备初始化函数分析 stm32 uart
  • 华为IP的考试费要好几千,想问一下这个证书的含金量怎么样?

    虽然华为认证HCIP考试只考笔试 题库稳 运气好的话刷题库就有可能会过 但是其实学的时候还是好好学的 要不然只为了考试而去背题 但是实际操作能力不行的话一样会被企业拒绝的 最重要的还是掌握华为认证HCIP的技能 证书只是找工作的一个敲门砖
  • 服务器系统这么做,服务器怎么做系统

    服务器怎么做系统 内容精选 换一换 无法直接从云备份控制台查看备份中的数据 您可以通过以下几种方式进行查看 云服务器备份使用云服务器备份创建镜像后 再使用镜像创建云服务器 登录云服务器 查看服务器中的数据 云硬盘备份使用云硬盘备份创建新的云
  • 算法题:完全二叉树的权值

    问题描述 给定一棵包含 N 个节点的完全二叉树 树上每个节点都有一个权值 按从 上到下 从左到右的顺序依次是 A1 A2 AN 如下图所示 现在要把相同深度的节点的权值加在一起 他想知道哪个深度的节点 权值之和最大 如果有多个深度的权值和同
  • 代理模式,以及Java的动态代理

    定义 为其他对象提供一种代理以控制对这个对象的访问 可以提供额外不同的操作 UML类图 Subject类 定义了RealSubject和Proxy的共用接口 这样就在任何使用RealSubject的地方都可以使用Proxy RealSubj