设计模式(二)- 代理模式

2023-11-03

代理模式

1.代理模式

在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。

在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口

1.1介绍

意图:在面向对象系统中,有些对象由于某些原因(比如某些操作需要安全控制),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问

主要解决:想在访问一个类时做一些控制。

如何解决:增加中间层。

关键代码:实现与被代理类组合。

1.2 应用实例

在访问对象的时候,如果需要鉴权,对访问者进行判断或者进行校验,可以再访问前做一下处理,或者如果需要打印流程日志,可以在访问过程中加入日志,方便判断,代理模式分为静态代理、动态代理

1.3 静态代理

静态代理需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类,这点是它的缺点,不方便扩展,需要加接口时候,所有的实现都要加同样的接口

1.4 动态代理

动态代理它可以直接给某一个目标(被代理 对象)对象(实现了某个或者某些接口)生成一个代理对象,利用的时Proxy中的newInstance反射来实现代理模式

1.4.1 Java.lang.reflect.Proxy类可以直接生成一个代理对象

Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)生成一个代理对象

  1. 参数1:ClassLoader loader 代理对象的类加载器 一般使用被代理对象的类加载器
  2. 参数2:Class<?>[] interfaces 代理对象的要实现的接口 一般使用的被代理对象实现的接口
  3. 参数3:InvocationHandler h (接口)执行处理类
1.4.2 InvocationHandler中的invoke()方法

invoke(Object proxy, Method method, Object[] args)方法:调用代理类的任何方法,此方法都会执行

  1. 参数1:代理对象(慎用)
  2. 参数2:当前执行的方法
  3. 参数3:当前执行的方法运行时传递过来的参数
  4. 返回值:当前方法执行的返回值
2.静态代理 代码
2.1 定义接口
package com.jzj.design.demo.proxyDesign.staticproxy;

/**
 * 方法的接口
 */
public interface IMethodDAO {
    void doSomeThing();
}
2.2 原始接口的实现

接口实现

package com.jzj.design.demo.proxyDesign.staticproxy;

public class LocalMethodImpl implements IMethodDAO {
    @Override
    public void doSomeThing() {
        System.out.println("原始的对象 方法调用");
    }
}
2.3 静态代理对象实现

实现同一个接口,通过构造函数初始化 代理对象,通过该对象调用,实现方法的调用

package com.jzj.design.demo.proxyDesign.staticproxy;

public class StaticProxyMethod implements IMethodDAO {


    private IMethodDAO teachDAO;


    /**
     * 静态代理 构造函数,初始化 接口对象
     *
     * @param teachDAO
     */
    public StaticProxyMethod(IMethodDAO teachDAO) {
        this.teachDAO = teachDAO;
    }


    @Override
    public void doSomeThing() {
        System.out.println("静态代理开始 可以加日志、鉴权 等等操作---------------------");
        teachDAO.doSomeThing();
        System.out.println("静态代理结束、输出日志,访问结束---------------------");
    }
}

2.4 静态代理结果
package com.jzj.design.demo.proxyDesign.staticproxy;

public class StaticProxyMain {
    public static void main(String[] args) {
        IMethodDAO methodDAO = new LocalMethodImpl();
        IMethodDAO staticProxy = new StaticProxyMethod(methodDAO);
        staticProxy.doSomeThing();
    }
}

在这里插入图片描述

3.动态代理 代码
3.1 定义接口
package com.jzj.design.demo.proxyDesign.dynamicproxy;

/**
 * 老师在教学 接口
 */
public interface ITeachDAO {
    void teach();
}

3.2 方法实现
package com.jzj.design.demo.proxyDesign.dynamicproxy;

/**
 * 老师在教学 实现
 */
public class TeacherServiceImpl implements ITeachDAO {
    @Override
    public void teach() {
        System.out.println("原始对象,老师在教书");
    }
}

3.3 动态代理实现

通过Proxy newInstance 反射构造对象,然后通过 InvocationHandler 来对具体的方法 进行增强处理

package com.jzj.design.demo.proxyDesign.dynamicproxy;

import java.lang.reflect.Proxy;

/**
 * 动态代理
 */
public class DynamicTeachProxy {
    /**
     * 目标对象
     */
    private Object target;

    //构造器 对目标对象初始化
    public DynamicTeachProxy(Object target) {
        this.target = target;
    }


    //给目标对象 反射生成一个代理对象
    public Object getProxyInstance() {
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                (proxy, method, args) -> {
                    System.out.println("--------动态代理- 老师教书前 准备工作--------");
                    Object value = method.invoke(target, args);
                    System.out.println("--------动态代理- 老师教书后 收尾工作--------");
                    return value;
                });
    }


}

3.4 动态代理结果
package com.jzj.design.demo.proxyDesign.dynamicproxy;

public class DynamicTestMain {
    public static void main(String[] args) {
        ITeachDAO target = new TeacherServiceImpl();

        //给目标对象 创建代理对象
        DynamicTeachProxy proxy = new DynamicTeachProxy(target) ;
        ITeachDAO proxyObject =(ITeachDAO) proxy.getProxyInstance();
        proxyObject.teach();
    }
}

在这里插入图片描述

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

设计模式(二)- 代理模式 的相关文章

  • 在 JTable 中移动行

    我使用 MVC 模式 并且有一个如下所示的 JTable List
  • 热重载在docker中运行的java程序

    我开发了一个java程序 应该在docker中运行 然而 我在调试docker中运行的java程序时遇到了很多痛苦 我在网上搜索 一些教程提出了像 spring dev tools 这样的工具 因为我的java程序是基于spring boo
  • Java 中的 XPath 节点集

    我在 eclipse 中有这段代码 NodeSet nodes NodeSet xPath evaluate expression inputSource XPathConstants NODESET 它给我 NodeSet 上的编译时错误
  • 如何将 Java 赋值表达式转换为 Kotlin

    java中的一些东西就像 int a 1 b 2 c 1 if a b c System out print true 现在它应该转换为 kotlin 就像 var a Int 1 var b Int 2 var c Int 1 if a
  • 在Windows上安装Java 11 OpenJDK(系统路径问题)

    Java 11 最近发布了 众所周知 这个版本没有安装文件 当然 要在没有安装程序的情况下安装 Java 我将系统设置 PATH 和 JAVA HOME 设置为解压缩 Java 11 的文件夹的地址 根据对类似问题的已接受回复建议 唯一的事
  • java.io.IOException: %1 不是有效的 Win32 应用程序

    我正在尝试对 XML 文档进行数字签名 为此我有两个选择 有一个由爱沙尼亚认证中心为程序员创建的库 还有一个由银行制作的运行 Java 代码的脚本 如果使用官方 认证中心 库 那么一切都会像魅力一样进行一些调整 但是当涉及到银行脚本时 它会
  • 使用 ANTLR 为 java 源代码生成抽象语法树

    如何使用 ANTLR 从 java src 代码生成 AST 有什么帮助吗 好的 步骤如下 前往ANTLR站点 http www antlr org 并下载最新版本 下载Java g和JavaTreeParser g文件来自here htt
  • HDFS:使用 Java / Scala API 移动多个文件

    我需要使用 Java Scala 程序移动 HDFS 中对应于给定正则表达式的多个文件 例如 我必须移动所有名称为 xml从文件夹a到文件夹b 使用 shell 命令我可以使用以下命令 bin hdfs dfs mv a xml b 我可以
  • 使用替换字符串中多个单词的最有效方法[重复]

    这个问题在这里已经有答案了 此刻我正在做 Example line replaceAll replaceAll cat dog replaceAll football rugby 我觉得那很丑 不确定有更好的方法吗 也许循环遍历哈希图 ED
  • Prim 的迷宫生成算法:获取相邻单元格

    我基于 Prim 算法编写了一个迷宫生成器程序 该算法是 Prim 算法的随机版本 从充满墙壁的网格开始 选择一个单元格 将其标记为迷宫的一部分 将单元格的墙壁添加到墙壁列表中 While there are walls in the li
  • Clip 在 Java 中播放 WAV 文件时出现严重延迟

    我编写了一段代码来读取 WAV 文件 大小约为 80 mb 并播放该文件 问题是声音播放效果很差 极度滞后 你能告诉我有什么问题吗 这是我的代码 我称之为doPlayJframe 构造函数内的函数 private void doPlay f
  • 反思 Groovy 脚本中声明的函数

    有没有一种方法可以获取 Groovy 脚本中声明的函数的反射数据 该脚本已通过GroovyShell目的 具体来说 我想枚举脚本中的函数并访问附加到它们的注释 Put this到 Groovy 脚本的最后一行 它将作为脚本的返回值 a la
  • 归并排序中的递归:两次递归调用

    private void mergesort int low int high line 1 if low lt high line 2 int middle low high 2 line 3 mergesort low middle l
  • 将多模块 Maven 项目导入 Eclipse 时出现问题 (STS 2.5.2)

    我刚刚花了最后一个小时查看 Stackoverflow com 上的线程 尝试将 Maven 项目导入到 Spring ToolSuite 2 5 2 中 Maven 项目有多个模块 当我使用 STS 中的 Import 向导导入项目时 所
  • 应用程序关闭时的倒计时问题

    我制作了一个 CountDownTimer 代码 我希望 CountDownTimer 在完成时重新启动 即使应用程序已关闭 但它仅在应用程序正在运行或重新启动应用程序时重新启动 因此 如果我在倒计时为 00 10 分钟 秒 时关闭应用程序
  • Windows 上的 Nifi 命令

    在我当前的项目中 我一直在Windows操作系统上使用apache nifi 我已经提取了nifi 0 7 0 bin zip文件输入C 现在 当我跑步时 bin run nifi bat as 管理员我在命令行上看到以下消息 但无法运行
  • java迭代器内部是如何工作的? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一个员工列表 List
  • KeyPressed 和 KeyTyped 混淆[重复]

    这个问题在这里已经有答案了 我搜索过之间的区别KeyPressedand KeyTyped事件 但我仍然不清楚 我发现的一件事是 Keypressed 比 KeyTyped 首先被触发 请澄清一下这些事件何时被准确触发 哪个适合用于哪个目的
  • Jackson 将单个项目反序列化到列表中

    我正在尝试使用一项服务 该服务为我提供了一个带有数组字段的实体 id 23233 items name item 1 name item 2 但是 当数组包含单个项目时 将返回该项目本身 而不是包含一个元素的数组 id 43567 item
  • Swagger/Openapi-Annotations:如何使用 $ref 生成 allOf?

    我正在生成 Rest 端点 包括添加OpenAPI Swagger对生成的代码进行注释 虽然它对于基本类型运行得很好 但我在自定义类方面遇到了一些问题 现在我有很多自定义类的重复架构条目 使用 Schema 实现 MyClass class

随机推荐

  • Android面试必刷Framewrok面试题(附答案),打破面试难点(2023年最新版)

    最近收到身边很多人反馈 现在的android面试 大多数企业除了对求职者的语言和编码等基础能力提出要求外 越来越强调对于 Framework 层的理解和 UI 框架的掌控能力 而完整的项目经历和多端知识也成了重要的加分项 于是小编收拾了一下
  • 【跨模态】【对比学习】CLIP:文本监督CV的预训练(2021)

    文章目录 前言 一 整体架构 1 训练 2 测试 迁移学习zero shot 3 prompt engineering and ensembling 二 实验 1 few shot与zero shot的对比 2 Representation
  • C#实现多语言切换

    代码 https github com tangbb1 C shop tree master 思路描述 窗体的language属性修改为自己需要设定语言 localizable属性改为true 在窗体上进行英文编辑 即可生成对应的资源文件
  • osgearth消除近裁剪平面离物体太近时的裁剪问题

    This will mitigate near clip plane issues if you zoom in close to the ground LogarithmicDepthBuffer buf buf install view
  • JavaScript 新增两个原始数据类型Record 和 Tuple

    JavaScript即将推出两个新的数据类型 Record 和 Tuple 这俩是啥呢 其实就是一个只读的 Object 和 Array 其实在其它语言中已经有类似的数据类型了 例如 Python 中也有 Tuple 元祖 这一类型 作用也
  • 优雅的后端参数验证javax.validation

    为什么要用validator javax validation的一系列注解可以帮我们完成参数校验 免去繁琐的串行校验 不然我们的代码就像下面这样 PostMapping save serial public Object save Requ
  • EDA14--DC脚本实例

    这里写目录标题 一 示例1 同步设计 fifo1 二 示例2 异步设计 fifo2 三 具体操作 fifo1为例 DC的所有理论知识已经简单的概述完了 包括 DC简介概念流程 逻辑推断 DC脚本命令 最后给出DC的两个示例 下面是大的目录
  • 18650锂电池充电方案及保护板电路构思

    18650锂电池充电方案及保护板电路构思 一 电路参数 1 充电电源为USB电源 额定电压为5V 2 蓄电池为18650锂电池 3 7V 容量2600mAh 3 负载电机参数 二 电路板功能要求 1 充电电压保护 防止因选用错误的充电器 过
  • JSONObject出现重复引用$ref

    现象 保存的时候红框里内容是一样的 结果JSON toJSONString的时候第二个就变成了 ref 原因 JSONObject 默认开启引用检测 重复引用对象时会被 ref代替 返回的json对象出现 ref 对象 地址值 解决办法 S
  • PhpStorm 基本设置

    更换皮肤 File gt Settings gt Appearance gt Theme 字体 File gt Settings gt Editor gt Colors Font gt font 点save as 然后再自定义 typo设置
  • oracle和sqlite区别,数据库sqlserver与sqlite的区别

    sqlserver 与sqlite的区别 sqlserver是大型数据库 常用于企业级应用的后台数据存储 sqlite 是轻量级数据库 对小数据量的数据存储方便 文件型数据库 其语法区别大 比如查询前10条数据 sqlserver SELE
  • 聊聊Api接口优化的几个方法

    转载 聊聊Api接口优化的几个方法 知乎 作为记录 用于学习
  • Vendor ID对照表(不定期更新)

    Vendor ID对照表 不定期更新 可自行查询原网址 8086 Intel Corporation 0731 Jingjia Microelectronics Co Ltd 1DB7 Phytium Technology Co Ltd 1
  • 归一化函数 normalized()

    1 归一化定义与作用 归一化就是要把需要处理的数据经过处理后 通过某种算法 限制在你需要的一定范围内 首先归一化是为了后面数据处理的方便 其次是保证程序运行时收敛加快 归一化的具体作用是归纳统一样本的统计分布性 归一化在0 1之间是统计的概
  • 攻防演练场景中的加密流量检测技术

    lt 引言 gt 在对抗日益激烈 加密手段逐渐成为主流的今天 攻防演练场景中的加密流量也已逐渐成为主流 对加密流量检测的技术变得愈发重要 目前针对攻防演练场景的加密流量检测主要分为解密后检测和不解密检测两大类 传统的解密检测拥有可以直接将加
  • 文心一言#帮我生成一段1分钟的短视频AI脚本

    视频标题 旅行者的一天 视频类型 旅游 视频时长 1分钟 视频描述 这是一个关于一个旅行者一天的故事 他早上起床后 先去了一家当地的早餐店 品尝了美味的当地早餐 接着 他去了一家博物馆 了解了当地的历史和文化 中午 他去了一家当地的餐厅 品
  • ubuntu上redis安装启动和停止

    在 Ubuntu 上操作 Redis 可以按照以下步骤进行 安装 Redis 使用以下命令安装 Redis sudo apt get update sudo apt get install redis server 设置开机自动启动 使用以
  • OOM Killer 持续更新中

    虚拟地址空间的概念都门儿清 Linux 认为用户进程调用malloc申请了动态内存后不见得马上就会使用这段内存进行写读操作 Linux使用了拖到最后的分配机制 用时分配机制 但是 即使是用时分配 也不见得总有内存可分配 当进程太多 显得内存
  • kotlin与java实现混编基础看这篇就够了

    前几年一直关注安卓 想换个方向 奔着移动端大步向前 由于比较懒就一直停留在想法 这不今天勤快点 动手搞了一个基础的java和kotlin混编 和大家总结分享一下 首先需要了解什么事kotlin kotlin中文网上面有详细的讲解 比如入门教
  • 设计模式(二)- 代理模式

    代理模式 文章目录 代理模式 1 代理模式 1 1介绍 1 2 应用实例 1 3 静态代理 1 4 动态代理 1 4 1 Java lang reflect Proxy类可以直接生成一个代理对象 1 4 2 InvocationHandle