代理设计模式,框架AOP思想

文章目录

    • 引言🤪
    • 代理对象(Proxy)
    • 如何开发一个代理对象
    • 开发中的业务层代码冗余问题
    • 开发静态代理类
    • 动态代理

引言🤪

代理 (proxy) ,举个生活中常见的现象,在之前网路还未走进大众的时代里,如果我们想买一些东西,只是直接去店里,现在网络普及了,互联网+shopping,使我们足不出户就可以办很多事,比如网上购物,注意啊,网上购物大多数都是有一个代收点,而不是直接送到你的手上,家里,为什么呢?,因为那样的代价会很大,影响效率,所以出现了代收点,我们再去代收点去拿到网购的货物,完成网购,那么,根据这个现象,如果放在编程中,我们就可以把这个代收点比做成是一个代理对象,在整个购物的过程中起到了一个代收的作用,同时他也介入了购物的一部分,OK

在这里插入图片描述

代理对象(Proxy)

代理:指的是一种设计模式
作用:在整个业务中完成一些 业务之外的附加操作,同时也可以中断整个业务
好处:专注于业务开发,对于一些附加操作,交予代理完成一些繁琐的重复的操作,好耶!

在这里插入图片描述

如何开发一个代理对象

1.代理对象要和原始业务对象有用一个规定,放在面向对象中就是实现同一个接口(interface)
2.代理对象依赖业务对象

开发中的业务层代码冗余问题

ShopService接口

//商品业务的接口
public interface ShopService {//添加商品void add();//下架商品void remove();//……
}

ShopService接口实现类ShopServiceImpl

public class ShopServiceImpl implements ShopService {@Overridepublic void add() {try {System.out.println("开启事务");System.out.println("处理添加商品业务逻辑,调用DAO~~~");System.out.println("提交事务");}catch (Exception e){System.out.println("回滚事务");e.printStackTrace();}}@Overridepublic void remove() {try {System.out.println("开启事务");System.out.println("处理添下架商品业务逻辑,调用DAO~~~");System.out.println("提交事务");}catch (Exception e){System.out.println("回滚事务");e.printStackTrace();}}
}

测试一下

public class ShopTest {public static void main(String[] args) {ShopServiceImpl shopService = new ShopServiceImpl();shopService.add();shopService.remove();}
}

是没有任何问题的,但是你会发现service控制事务的代码大量冗余,一点也不优雅,在做重复的事情,如果是你,你会怎么优化呢?问题给到你,🤪

开启事务
处理添加商品业务逻辑,调用DAO~~~
提交事务
开启事务
处理添下架商品业务逻辑,调用DAO~~~
提交事务

开发静态代理类

ShopServiceStaticProxy

/*静态代理类和业务类实现同一个接口*/
public class ShopServiceStaticProxy implements ShopService {/*静态代理类依赖业务类*/private ShopService shopService;public void setShopService(ShopService shopService) {this.shopService = shopService;}@Overridepublic void add() {try {System.out.println("开启事务");shopService.add();System.out.println("提交事务");}catch (Exception e){System.out.println("回滚事务");e.printStackTrace();}}@Overridepublic void remove() {try {System.out.println("开启事务");shopService.remove();System.out.println("提交事务");}catch (Exception e){System.out.println("回滚事务");e.printStackTrace();}}
}

ShopServiceImpl优化后的专注于业务

public class ShopServiceImpl implements ShopService {@Overridepublic void add() {System.out.println("处理添加商品业务逻辑,调用DAO~~~");}@Overridepublic void remove() {System.out.println("处理添下架商品业务逻辑,调用DAO~~~");}
}

能否可行,测试,必须行

public class ShopTest {public static void main(String[] args) {ShopServiceImpl shopService = new ShopServiceImpl();ShopServiceStaticProxy shopServiceStaticProxy = new ShopServiceStaticProxy();shopServiceStaticProxy.setShopService(shopService);shopServiceStaticProxy.add();shopServiceStaticProxy.remove();}
}
开启事务
处理添加商品业务逻辑,调用DAO~~~
提交事务
开启事务
处理添下架商品业务逻辑,调用DAO~~~
提交事务

perfect,现在看起来优雅很多了

往往在开发我们书写的不仅仅是一个业务层,两个业务层,而我们的业务层会有很多,如果为每一个业务层开发一个静态代理类,不仅没有减轻工作量,甚至让我们的工作量多了一倍不止怎么解决以上这个问题呢?
解决方案:
为业务层在运行过程中动态创建代理类,通过动态代理类去解决我们现有业务层中业务代码冗余的问题

动态代理

有了静态代理的基础之后,来看看更好玩的动态代理,它是spring框架AOP的实现原理,以及很多框架的核心思想及落地实现
GO

通过jdk提供的 Proxy 类,动态为现有的业务生成代理类

参数一:当前线程类加载器 classLoader
参数二:生成代理类的接口类型
参数三:通过代理类对象调用方法时会优先进入参数三中的invoke方Proxy.newProxyInstance(loader, interfaces, h);//返回值就是动态代理对象

AOP的原理就是对动态代理的封装

还有 MyBatis 框架中的 getMapper(xxx.class),就是使用了动态代理对象

public class TestDynamicProxy {public static void main(String[] args) {//参数1: classLoader 类加载器ClassLoader classLoader = Thread.currentThread().getContextClassLoader();//参数2: Class[] 动态代理对象的接口类型的数组Class[] classes = {ShopService.class};//参数3: InvocationHandler接口类型 invoke 方法 写附加操作ShopService userServiceDyProxy = (ShopService) Proxy.newProxyInstance(classLoader, classes, new InvocationHandler() {@Override//通过动态代理对象调用自己里面代理方法时会优先指定InvocationHandler类中invoke// invoke方法参数//1. 当前创建好的代理对象//2. 当前代理对象执行的方法对象//3. 当前代理对象执行方法的参数public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("当前执行的方法:" + method.getName());try {System.out.println("开启事务");//调用目标类中的业务方法Object invoke = method.invoke(new ShopServiceImpl(), args);System.out.println("提交事务");return invoke;}catch (Exception e){System.out.println("回滚事务");e.printStackTrace();}return null;}});System.out.println(userServiceDyProxy.getClass());userServiceDyProxy.remove();userServiceDyProxy.add();}
}
class com.sun.proxy.$Proxy0
当前执行的方法:remove
开启事务
处理添下架商品业务逻辑,调用DAO~~~
提交事务
当前执行的方法:add
开启事务
处理添加商品业务逻辑,调用DAO~~~
提交事务

完美完成,Perfect realization,尽管动态代理的代码很难理解,但是这是必经之路,加油,战胜它,奥里给,这就是全部内容了,拜拜了 🚀

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第十九届全国大学生智能汽车竞赛智慧巡检创意组赛程安排通知

各位老师和同学们大家好: 通知一:经过和大赛组委会、承办校协商确定,天途智慧巡检创意组线下预选赛和总决赛将在吉林大学(东北赛区)举办,赛程如下: 地点:吉林大学前卫南区体育馆 地…

Nginx之文件下载服务器

1.概述 在对外分享文件时,利用Nginx搭建一个简单的下 载文件管理服务器,文件分享就会变得非常方便。利 用Nginx的诸多内置指令可实现自动生成下载文件列表 页、限制下载带宽等功能。配置样例如下: server {listen 8080;server_name localhos…

有了MES、ERP,质量管理为什么还需要QMS?

在制造业,质量管理始终是企业管理中永恒的主题。品质管理要想做得更好,企业必须掌握足够多、足够有用的数据和信息,实现质量管理信息化。很多中小企业也很困惑,是否有必要上线QMS质量管理系统? 一、为什么企业需要QMS的…

Graph RAG 的力量:智能搜索的未来

随着世界越来越依赖数据,对准确、高效的搜索技术的需求从未如此高涨。传统搜索引擎虽然功能强大,但往往难以满足用户复杂而细微的需求,尤其是在处理长尾查询或专业领域时。Graph RAG(检索增强生成)正是在这种情况下应运…

Python-Socket网络编程简单示例

# TCP 服务端程序 server.py # 导入socket 库 from socket import *# 主机地址为空字符串,表示绑定本机所有网络接口ip地址 # 等待客户端来连接 IP # 端口号 PORT 50000 # 定义一次从socket缓冲区最多读入512个字节数据 BUFLEN 512# 实例化一个socket对象 # 参…

第1讲:创建vite工程,使用框架为Vanilla时,语言是typescript,修改http端口的方法

直接在项目根目录创建 vite.config.ts文件。 在该文件中添加内容: import { defineConfig } from vite;export default defineConfig({server: {port: 7777,}, });最后尝试运行package.json中的Debug

AI大模型的TTS评测

L-MTL(Large Multi-Task Learning)Models 是一种大规模多任务学习模型,通过结合 Mixture of Experts(MMoE)框架与 Transformer 模型,实现对 TTS(Text-to-Speech)系统中多个评估指标的…

今日分享丨点亮这四个技能,你也可以成为可视化专家

引言 以大数据、人工智能等为代表的新质生产力时代已悄然而至,央企、国企逐步意识到数据资源展示对于经营管理的重要性和紧迫性。数据可视化成为连接用户与数据的桥梁,藉由设计师的巧手,把复杂抽象的数据以基于管理需求,转化为直…

PAT B1018.锤子剪刀布

题目描述 大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则如图3-1所示。 现给出两人的交锋记录,请统计双方的胜、平、负次数,并给出双方分别出什么手势的胜算最大。输入格式 第一行给出正整数N(≤10),即双方交锋的次数。随后N行,每行给…

探索Web Components

title: 探索Web Components date: 2024/6/16 updated: 2024/6/16 author: cmdragon excerpt: 这篇文章介绍了Web Components技术,它允许开发者创建可复用、封装良好的自定义HTML元素,并直接在浏览器中运行,无需依赖外部库。通过组合HTML模…

Top10在线音频剪辑软件,你了解几款?(免费分享)

多年来,随着音乐制作人和音频工程师的需求不断增长,音频剪辑软件领域经历了巨大的发展。最新的音频剪辑软件提供了从基本录制到最终发布所需的一切功能。其中一些软件专为播客设计,一些软件是免费的,并且一些软件提供了出色的音效…

python读取excel中的图片超链接,批量下载到本地

1、代码 import xlrd import requestsread_path C:\\Users\\asus\\Desktop\\大法\\公务员\\国考\\行测\\1-推理判断\\URLs.xlsx bk xlrd.open_workbook(read_path) shxrange range(bk.nsheets) sh bk.sheet_by_name("Sheet2") nrows sh.nrows ncols sh.ncols …

【自撰写】【国际象棋入门】第6课 常见术语分析(一)吃双和抽将

第6课 常见术语分析(一)吃双和抽将 本次课中,我们介绍几种最为常见和常用的(单步棋形成)的局面、术语并对其进行简单的分析。一般说来,这些局面都会给予一方以“立竿见影”的优势,或者引向之后…

“鸿蒙开发之图片下载”--案例问题整理

鸿蒙开发之图片下载 关于以上连接中案例demo使用问题整理如下图 而且在写这个案例的时候记得添加权限 "requestPermissions":[{"name" : "ohos.permission.INTERNET"}]

Java多线程设计模式之不可变对象(Immutable Object)模式

简介 多线程共享变量的情况下,为了保证数据一致性,往往需要对这些变量的访问进行加锁。而锁本身又会带来一些问题和开销。Immutable Object模式使得我们可以在不加锁的情况下,既保证共享变量访问的线程安全,又能避免引入锁可能带…

20240619在飞凌OK3588-C的Linux R4系统下查找MIPI YUV摄像头的csi size err

20240619在飞凌OK3588-C的Linux R4系统下查找MIPI YUV摄像头的csi size err 2024/6/19 14:00 缘起,公司使用LVDS OUT的机芯,4LANE的LVDS输出。1920x108030分辨率(1080p/30) 通过FPGA转换为2LANE的MIPI OUT之后进RK3588/OK3588-C。…

sqlite3指令操作-linux

1.查看当前数据库位置 2.查看当前数据库文件下有哪些表 3.显示 某表创建时的SQL语句 4.打开、关闭显示列标题; 5.列对齐显示 6.列以‘,’分隔显示 .separator 7.查询表信息 8.插入消息 9.删除某一行内容 10.修改某行某列内容 11.修改表名字 alter tab…

浅谈golang字符编码

1、 Golang 字符编码 Golang 的代码是由 Unicode 字符组成的,并由 Unicode 编码规范中的 UTF-8 编码格式进行编码并存储。 Unicode 是编码字符集,囊括了当今世界使用的全部语言和符号的字符。有三种编码形式:UTF-8,UTF-16&#…

2024年项目进度控制软件大比拼:找出适合您团队的最佳工具

本文整理了9大热门项目进度控制软件:PingCode、Worktile、Monday.com、Asana、Trello、Jira、ClickUp、Wrike、Zoho Projects。并且进行详细介绍对比。 在项目管理工具的选择上,不同规模的团队有着各自的需求和偏好。例如,小型团队倾向于选择…

新手搭建Magic-API

项目场景: 我本是一个前端和GIS开发工程师,但新单位并没有配置完整的开发团队,确切说目前只有我一个人做开发,那么肯定避免不了要研究下后端。最近有一个小程序要开发,管理平台我直接用的fastAdminthinkphp写完了页面…