Spring 学习(六)代理模式

10. 代理模式

  • 案例

在这里插入图片描述

10.1 静态代理

  • 角色分析

    • 抽象角色:一般使用接口或者抽象类实现。
    • 真实角色:被代理的角色。
    • 代理角色:代理真实角色,含附属操作。
    • 客户:访问代理对象的角色。
  • 租房案例

    • 定义租赁接口

      /*** TODO* 租房* @author why* @since 2021/7/6 9:06*/
      public interface Rent {public void rent();
      }
      
    • 定义真实角色

      /*** TODO* 房东* @author why* @since 2021/7/6 9:10*/
      public class Landlord implements Rent {public void rent() {System.out.println("房东要出租房子");}
      }
      
    • 定义代理角色

      /*** TODO* 中介* @author why* @since 2021/7/6 9:14*/
      public class Proxy implements Rent {private Landlord landlord;public Proxy() {}public Proxy(Landlord landlord) {this.landlord = landlord;}/*** 出租房子*/public void rent() {seeHouse();landlord.rent();signContract();fee();}/*** 看房*/public void seeHouse(){System.out.println("中介带租客看房");}/*** 收中介费*/public void fee(){System.out.println("收中介费");}/*** 签合同*/public void signContract(){System.out.println("签租赁合同");}}
      
    • 客户端访问代理角色

      /*** TODO* 租客* @author why* @since 2021/7/6 9:12*/
      public class Client {public static void main(String[] args) {// 房东想要出租房子Landlord landlord = new Landlord();// 中介帮助房东出租房子,包含了附加操作Proxy proxy = new Proxy(landlord);// 租客找中介租房子proxy.rent();}
      }
      
  • 模式优点

    • 可以使真实角色的操作更加纯粹,不必关注一些公共业务。
    • 公共业务交给代理角色,实现了业务的分工。
    • 公共业务发生扩展时,方便集中管理。
  • 模式缺点

    • 一个真实角色就会产生一个代理角色,代码量会翻倍,开发效率会变低。
  • 业务模拟

    • 抽象 AOP 机制

      在这里插入图片描述

    • 定义用户操作接口

      /*** TODO* 用户服务接口* @author why* @since 2021/7/6 9:38*/
      public interface UserService {public void add();public void delete();public void update();public void query();
      }
      
    • 定义业务操作实现类

      /*** TODO* 用户接口实现类(真实对象)* @author why* @since 2021/7/6 9:40*/
      public class UserServiceImpl implements UserService {public void add() {System.out.println("增加一个用户");}public void delete() {System.out.println("删除一个用户");}public void update() {System.out.println("修改一个用户");}public void query() {System.out.println("查询一个用户");}
      }
      
    • 定义代理

      /*** TODO* 代理* @author why* @since 2021/7/6 9:57*/
      public class UserServiceProxy implements UserService {private UserService userService;public void setUserService(UserService userService) {this.userService = userService;}public void add() {log("add");userService.add();}public void delete() {log("delete");userService.delete();}public void update() {log("update");userService.update();}public void query() {log("query");userService.query();}// 日志方法public void log(String msg) {System.out.println("[Debug] 使用了"+ msg +"方法");}
      }
      
    • 定义客户端

      /*** TODO* 客户端* @author why* @since 2021/7/6 9:44*/
      public class Client {public static void main(String[] args) {UserServiceImpl userService = new UserServiceImpl();UserServiceProxy userServiceProxy = new UserServiceProxy();userServiceProxy.setUserService(userService);userServiceProxy.add();}
      }
      

10.2 动态代理

  • 动态代理和静态代理的角色一样

  • 动态代理的代理类是动态生成的,不需要编写。

  • 动态代理分为基于接口的动态代理和基于类的动态代理。

    • 基于接口 — JDK 动态代理
    • 基于类 — CGLIB
    • Java 字节码实现 — Javasist
  • 租房案例

    • 定义租赁接口

      /*** TODO* 租房* @author why* @since 2021/7/6 9:06*/
      public interface Rent {public void rent();
      }
      
    • 定义真实角色(房东)

      /*** TODO* 房东* @author why* @since 2021/7/6 9:10*/
      public class Landlord implements Rent {public void rent() {System.out.println("房东要出租房子");}
      }
      
    • 构造代理类生成器

      /*** TODO* 自动生成代理类* @author why* @since 2021/7/6 13:43*/
      public class ProxyInvocationHandler implements InvocationHandler {// 被代理的接口private Rent rent;public void setRent(Rent rent) {this.rent = rent;}// 获得代理类public Object getProxy(){return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(), this);}// 处理代理实例并返回结果public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 动态代理由反射机制实现Object result = method.invoke(rent, args);return result;}
      }
      
    • 定义客户端

      /*** TODO* 客户端* @author why* @since 2021/7/6 13:54*/
      public class Client {public static void main(String[] args) {// 真实角色Landlord landlord = new Landlord();// 代理角色(由 InvocationHandler 获取)ProxyInvocationHandler pih = new ProxyInvocationHandler();// 通过调用处理程序处理要调用的接口对象pih.setRent(landlord);Rent proxy = (Rent) pih.getProxy();proxy.rent();}
      }
      
  • 模式优点

    • 可以使真实角色的操作更加纯粹,不必关注一些公共业务。
    • 公共业务交给代理角色,实现了业务的分工。
    • 公共业务发生扩展时,方便集中管理。
    • 一个动态代理类代理的是一个接口,一般就是一类业务。
    • 一个动态代理可以代理多个类,前提是这些类实现了同一个接口。
  • 业务模拟

    • 定义用户操作接口

      /*** TODO* 用户服务接口* @author why* @since 2021/7/6 9:38*/
      public interface UserService {public void add();public void delete();public void update();public void query();
      }
      
    • 定义业务操作实现类

      /*** TODO* 用户接口实现类(真实对象)* @author why* @since 2021/7/6 9:40*/
      public class UserServiceImpl implements UserService {public void add() {System.out.println("增加一个用户");}public void delete() {System.out.println("删除一个用户");}public void update() {System.out.println("修改一个用户");}public void query() {System.out.println("查询一个用户");}
      }
      
    • 定义代理生成器

      /*** TODO* 自动生成代理类* @author why* @since 2021/7/6 13:43*/
      public class ProxyInvocationHandler implements InvocationHandler {// 被代理的接口private Object target;public void setTarget(Object target) {this.target = target;}// 获得代理类public Object getProxy(){return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);}// 处理代理实例并返回结果public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {log(method.getName());// 动态代理由反射机制实现return method.invoke(target, args);}public void log(String msg){System.out.println("执行了" + msg + "方法");}
      }
      
    • 定义客户端

      /*** TODO* 客户端* @author why* @since 2021/7/6 15:00*/
      public class Client {public static void main(String[] args) {UserServiceImpl userService = new UserServiceImpl();ProxyInvocationHandler pih = new ProxyInvocationHandler();pih.setTarget(userService);UserService proxy = (UserService) pih.getProxy();proxy.add();}
      }
      

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/142347.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL 基础

本系列文章为【狂神说 Java 】视频的课堂笔记,若有需要可配套视频学习。 1. 简介 数据库(DB,Database)是安装在操作系统上的存储数据的软件。 关系型数据库(RDB)以行列形式存储数据。 非关系型数据库&am…

竞赛选题 基于视觉的身份证识别系统

0 前言 🔥 优质竞赛项目系列,今天要分享的是 基于机器视觉的身份证识别系统 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🧿 更多资料, 项目分享: https://gitee.com/dancheng-sen…

第二届全国高校计算机技能竞赛——Java赛道

第二届全国高校计算机技能竞赛——Java赛道 小赛跳高 签到题 import java.util.*; public class Main{public static void main(String []args) {Scanner sc new Scanner(System.in);double n sc.nextDouble();for(int i 0; i < 4; i) {n n * 0.9;}System.out.printf(&…

JavaScript系列从入门到精通系列第四篇:JavaScript基本语法(二)

文章目录 前言 一&#xff1a;Number类型 1&#xff1a;字符串与Number类型 2&#xff1a;检查数据类型 3&#xff1a;Number最大值 4&#xff1a;Number四则运算精确性 二&#xff1a;布尔值 1&#xff1a;布尔值数量 2&#xff1a;布尔值类型查看 三&#xff1a;N…

基于微信小程序的电影院订票系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言运行环境说明用户微信小程序端的主要功能有&#xff1a;管理员的主要功能有&#xff1a;具体实现截图详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考论文参考源码获取 前言 &#x1f497;博主介绍&…

python -文件相关操作

文章目录 前言python -文件相关操作1. 读取文件1.1. 读取整个文件内容1.2. 读取文件的一行内容1.3. 将文件的内容按行存储到一个列表中 2. 写入文件3. 删除文件4. 追加文件5. 遍历文件5.1. 使用 os 模块 遍历文件5.2. # 使用 glob 模块 遍历文件5.3. 使用os.listdir() 函数遍历…

LeetCode 接雨水 双指针

原题链接&#xff1a; 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 题面&#xff1a; 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a…

TS编译选项——不允许使用隐式any类型、不明确类型的this、严格检查空值、编译后文件自动设置严格模式

一、不允许使用隐式any类型 在tsconfig.js文件中配置noImplicitAny属性 {"compilerOptions": {// 不允许使用隐式any类型"noImplicitAny": true} } 开启后即可禁止使用隐式的any类型 注意&#xff1a;显式的any类型并不会被禁止 二、不允许使用不明确类…

uniapp——实现base64格式二维码图片生成+保存二维码图片——基础积累

最近在做二维码推广功能&#xff0c;自从2020年下半年到今天&#xff0c;大概有三年没有用过uniapp了&#xff0c;而且我之前用uniapp开发的程序还比较少&#xff0c;因此很多功能都浪费了很多时间去查资料&#xff0c;现在把功能记录一下。 这里写目录标题 效果图1.base64生成…

算法基础之归并排序

一、归并排序的形象理解 原题链接 示例代码 void merge_sort(int q[], int l, int r) {if (l > r) return;int mid l r >> 1;merge_sort(q, l, mid), merge_sort(q, mid 1, r);int k 0, i l, j mid 1;while (i < mid && j < r) //第一处if (q[i]…

通过410s读取电表数据并接入物联网平台

通过410s读取电表数据并接入物联网平台 设备接线准备设备调试代码实现Modbus TCP Client 读取电表数据读取寄存器数据转成32bit Float格式然后使用modbusTCP Client 读取数据 使用mqtt协议接入物联网平台最终代码实现 设备接线准备 设备调试 代码实现 Modbus TCP Client 读取…

LeetCode刷题

一 螺旋矩阵 题目链接&#xff1a;59. 螺旋矩阵 II - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 给你一个正整数 n &#xff0c;生成一个包含 1 到 n2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 示例 1&#xff1a;…

【论文阅读 08】Adaptive Anomaly Detection within Near-regular Milling Textures

2013年&#xff0c;太老了&#xff0c;先不看 比较老的一篇论文&#xff0c;近规则铣削纹理中的自适应异常检测 1 Abstract 在钢质量控制中的应用&#xff0c;我们提出了图像处理算法&#xff0c;用于无监督地检测隐藏在全局铣削模式内的异常。因此&#xff0c;我们考虑了基于…

如何正确使用MySQL的索引呢?

前言: 📕作者简介:热爱编程的小七,致力于C、Java、Python等多编程语言,热爱编程和长板的运动少年! 📘相关专栏Java基础语法,JavaEE初阶,数据库,数据结构和算法系列等,大家有兴趣的可以看一看。 😇😇😇有兴趣的话关注博主一起学习,一起进步吧! 一、索引使用…

探索创意的新辅助,AI与作家的完美合作

在现代社会&#xff0c;文学创作一直是人类精神活动中的重要一环。从古典文学到现代小说&#xff0c;从诗歌到戏剧&#xff0c;作家们以他们的独特视角和文学天赋为我们展示了丰富多彩的人生世界。而近年来&#xff0c;人工智能技术的快速发展已经渗透到各行各业&#xff0c;文…

【数据结构】二叉树的销毁 二叉树系列所有源代码(终章)

目录 一&#xff0c;二叉树的销毁 二&#xff0c;二叉树系列所有源代码 BTee.h BTee.c Queue.h Queue.c 一&#xff0c;二叉树的销毁 二叉树建好了&#xff0c;利用完了&#xff0c;也该把申请的动态内存空间给释放了&#xff0c;那要如何释放呢&#xff1f; 我们还是以…

LeetCode力扣020:有效的括号

有效的括号 实现思路 设立判定条件遍历的范围 代码实现 class Solution(object):def isValid(self, s):""":type s: str:rtype: bool"""nlen(s)for i in range(0,n-1):if s[i]( and s[i1]!):return Falseif s[i][ and s[i1]!]:return Falseif s…

02Redis的命令行客户端和桌面客户端的下载和安装

Redis桌面客户端 安装完成Redis服务,我们就可以在Redis的客户端操作Redis的数据库实现数据的CRUD了,客户端分为三类命令行客户端, 图形化桌面客户端,编程客户端 命令行客户端 Redis安装完成后就自带了命令行客户端: redis-cli [options] [commonds] -h选项&#xff1a;指定…

Jenkins+Allure+Pytest的持续集成

一、配置 allure 环境变量 1、下载 allure是一个命令行工具&#xff0c;可以去 github 下载最新版&#xff1a;https://github.com/allure-framework/allure2/releases 2、解压到本地 3、配置环境变量 复制路径如&#xff1a;F:\allure-2.13.7\bin 环境变量、Path、添加 F:\a…

从零开始的 MyBatis 拦截器之旅:实战经验分享

文章目录 MyBatis拦截器可以做什么&#xff1f;Mybatis核心对象介绍四大核心对象如何实现&#xff1f;接口讲解Interceptor接口intercept方法plugin方法setProperties 完整SQL打印拦截器实战拦截器实现拦截器注册 MyBatis拦截器可以做什么&#xff1f; MyBatis拦截器是MyBatis…