Spring之代理模式

1、概念

1.1 介绍

二十三种设计模式中的一种,属于结构型模式。它的作用就是通过提供一个代理类,让我们在调用目标方法的时候,不再是直接对目标方法进行调用,而是通过代理类间接调用。让不属于目标方法核心逻辑的代码从目标方法中剥离出来——解耦。调用目标方法时先调用代理对象的方法,减少对目标方法的调用和打扰,同时让附加功能能够集中在一起也有利于统一维护。

在这里插入图片描述
使用代理后:
在这里插入图片描述
②生活中的代理

  • 广告商找大明星拍广告需要经过经纪人
  • 合作伙伴找大老板谈合作要约见面时间需要经过秘书
  • 房产中介是买卖双方的代理
1.2 相关术语
  • 代理:将非核心逻辑剥离出来以后,封装这些非核心逻辑的类、对象、方法。
  • 目标:被代理“套用”了非核心逻辑代码的类、对象、方法。

2 静态代理

    public interface Calculator {int add(int i, int j);int sub(int i, int j);int mul(int i, int j);int div(int i, int j);}
    package com.giser.java.spring6.calcu.impl;import com.giser.java.spring6.calcu.Calculator;/*** @author giserDev* @description 基础实现* @date 2024-01-06 23:41:55*/public class CalculatorImpl implements Calculator {@Overridepublic int add(int i, int j) {int result = i + j;System.out.println("方法内部 result = " + result);return result;}@Overridepublic int sub(int i, int j) {int result = i - j;System.out.println("方法内部 result = " + result);return result;}@Overridepublic int mul(int i, int j) {int result = i * j;System.out.println("方法内部 result = " + result);return result;}@Overridepublic int div(int i, int j) {int result = i / j;System.out.println("方法内部 result = " + result);return result;}}

创建静态代理类

    package com.giser.java.spring6.calcu.impl;import com.giser.java.spring6.calcu.Calculator;/*** @author giserDev* @description* 提出问题** ①现有代码缺陷** 针对带日志功能的实现类,我们发现有如下缺陷:** - 对核心业务功能有干扰,导致程序员在开发核心业务功能时分散了精力* - 附加功能分散在各个业务功能方法中,不利于统一维护** ②解决思路** 解决这两个问题,核心就是:解耦。我们需要把附加功能从业务功能代码中抽取出来。** ③困难** 解决问题的困难:要抽取的代码在方法内部,靠以前把子类中的重复代码抽取到父类的方式没法解决。所以需要引入新的技术。* @date 2024-01-06 23:43:25*/public class CalculatorLogImpl implements Calculator {@Overridepublic int add(int i, int j) {System.out.println("[日志] add 方法开始了,参数是:" + i + "," + j);int result = i + j;System.out.println("方法内部 result = " + result);System.out.println("[日志] add 方法结束了,结果是:" + result);return result;}@Overridepublic int sub(int i, int j) {System.out.println("[日志] sub 方法开始了,参数是:" + i + "," + j);int result = i - j;System.out.println("方法内部 result = " + result);System.out.println("[日志] sub 方法结束了,结果是:" + result);return result;}@Overridepublic int mul(int i, int j) {System.out.println("[日志] mul 方法开始了,参数是:" + i + "," + j);int result = i * j;System.out.println("方法内部 result = " + result);System.out.println("[日志] mul 方法结束了,结果是:" + result);return result;}@Overridepublic int div(int i, int j) {System.out.println("[日志] div 方法开始了,参数是:" + i + "," + j);int result = i / j;System.out.println("方法内部 result = " + result);System.out.println("[日志] div 方法结束了,结果是:" + result);return result;}}

静态代理的问题:

静态代理确实实现了解耦,但是由于代码都写死了,完全不具备任何的灵活性。就拿日志功能来说,将来其他地方也需要附加日志,那还得再声明更多个静态代理类,那就产生了大量重复的代码,日志功能还是分散的,没有统一管理。提出进一步的需求:将日志功能集中到一个代理类中,将来有任何日志需求,都通过这一个代理类来实现。这就需要使用动态代理技术了。

3 动态代理

在这里插入图片描述

package com.giser.spring6.calcu.impl.dynamicproxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;/*** @author giserDev* @description 代理工厂类* @date 2024-01-06 23:52:21*/
public class DynamicProxyFactory {/*** 被持有的被代理对象*/private Object target;public DynamicProxyFactory(Object target) {this.target = target;}/*** 创建代理对象* @return 代理对象*/public Object getProxy(){return Proxy.newProxyInstance(// 代理对象的类加载器target.getClass().getClassLoader(),// 代理对象实现的接口列表target.getClass().getInterfaces(),// 处理器new InvocationHandler() {/**** @param proxy the proxy instance that the method was invoked on*              代理对象** @param method the {@code Method} instance corresponding to* the interface method invoked on the proxy instance.  The declaring* class of the {@code Method} object will be the interface that* the method was declared in, which may be a superinterface of the* proxy interface that the proxy class inherits the method through.*               代理对象需要实现的方法** @param args an array of objects containing the values of the* arguments passed in the method invocation on the proxy instance,* or {@code null} if interface method takes no arguments.* Arguments of primitive types are wrapped in instances of the* appropriate primitive wrapper class, such as* {@code java.lang.Integer} or {@code java.lang.Boolean}.*             method对应的方法参数** @return* @throws Throwable*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object result = null;try {System.out.println("[动态代理][日志] "+method.getName()+",参数:"+ Arrays.toString(args));result = method.invoke(target, args);System.out.println("[动态代理][日志] "+method.getName()+",结果:"+ result);} catch (Exception e) {e.printStackTrace();System.out.println("[动态代理][日志] "+method.getName()+",异常:"+e.getMessage());} finally {System.out.println("[动态代理][日志] "+method.getName()+",方法执行完毕");}return result;}});}}

测试

package com.giser.spring6;import com.giser.spring6.calcu.Calculator;
import com.giser.spring6.calcu.impl.CalculatorImpl;
import com.giser.spring6.calcu.impl.dynamicproxy.DynamicProxyFactory;/*** @author giserDev* @description 动态代理测试* @date 2024-01-07 00:02:54*/
public class DynamicProxyTest {public static void main(String[] args) {DynamicProxyFactory dynamicProxyFactory = new DynamicProxyFactory(new CalculatorImpl());Calculator proxy = (Calculator) dynamicProxyFactory.getProxy();int add = proxy.add(1, 3);}}

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

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

相关文章

Python 面向对象之反射

Python 面向对象之反射 【一】概念 反射是指通过对象的属性名或者方法名来获取对象的属性或调用方法的能力反射还指的是在程序额运行过程中可以动态获取对象的信息(属性和方法) 【二】四个内置函数 又叫做反射函数 万物皆对象(整数、字符串、函数、模块、类等等…

后端开发——JDBC的学习(三)

本篇继续对JDBC进行总结: ①通过Service层与Dao层实现转账的练习; ②重点:由于每次使用连接就手动创建连接,用完后就销毁,这样会导致资源浪费,因此引入连接池,练习连接池的使用; …

霍兰德职业兴趣测试 60题(免费版)

霍兰德职业兴趣理论从兴趣的角度出发探索职业指导的问题,明确了职业兴趣的人格观念,使得人们对于职业兴趣的认识有了质的变化。在霍兰德职业兴趣理论提出来之前,职业兴趣和职业环境二者分别独立存在,正是霍兰德的总结,…

阿里云服务器8080端口怎么打开?在安全组中设置

阿里云服务器8080端口开放在安全组中放行,Tomcat默认使用8080端口,8080端口也用于www代理服务,阿腾云atengyun.com以8080端口为例来详细说下阿里云服务器8080端口开启教程教程: 阿里云服务器8080端口开启教程 阿里云服务器8080端…

[通俗易懂]c语言中指针变量和数值之间的关系

一、指针变量的定义 在C语言中,指针变量是一种特殊类型的变量,它存储的是另一个变量的内存地址。指针变量可以用来间接访问和操作内存中的其他变量。指针变量的定义如下: 数据类型 *指针变量名;其中,数据类型可以是任…

jenkins安装报错:No such plugin: cloudbees-folder

jenkins安装报错:No such plugin: cloudbees-folder 原因是缺少cloudbees-folder.hpi插件 解决: 一,重新启动 http://xxx:8800/restart 二,跳到重启界面时,点击系统设置 三,找到安装插件,然…

Python双端队列的3种实现及应用

概述 双端队列(deque,全名double-ended queue)是一种具有队列和栈性质的线性数据结构。双端队列也拥有两端:队首(front)、队尾(rear),但与队列不同的是,插入…

【pytorch学习】 深度学习 教程 and 实战

pytorch编程实战博主:https://github.com/lucidrains https://github.com/lucidrains/vit-pytorch

从0到1入门C++编程——04 类和对象之封装、构造函数、析构函数、this指针、友元

文章目录 一、封装二、项目文件拆分三、构造函数和析构函数1.构造函数的分类及调用2.拷贝函数调用时机3.构造函数调用规则4.深拷贝与浅拷贝5.初始化列表6.类对象作为类成员7.静态成员 四、C对象模型和this指针1.类的对象大小计算2.this指针3.空指针访问成员函数4.const修饰成员…

C#,入门教程(08)——基本数据类型及使用的基础知识

上一篇: C#,入门教程(07)——软件项目的源文件与目录结构https://blog.csdn.net/beijinghorn/article/details/124139947 数据类型用于指定数据体(DataEntity,包括但不限于类或结构体的属性、变量、常量、函数返回值)…

16、Kubernetes核心技术 - 节点选择器、亲和和反亲和

目录 一、概述 二、节点名称 - nodeName 二、节点选择器 - nodeSelector 三、节点亲和性和反亲和性 3.1、亲和性和反亲和性 3.2、节点硬亲和性 3.3、节点软亲和性 3.4、节点反亲和性 3.5、注意点 四、Pod亲和性和反亲和性 4.1、亲和性和反亲和性 4.2、Pod亲和性/反…

stable diffusion 进阶教程-controlnet详解(持续更新中)

说明 插件下载链接:https://pan.baidu.com/s/1-qmJzqcB72nTv_2QLmR-gA?pwd=8888 提取码: 8888 讨论Q群:830970289 个人微信:mindcarver 如果在按着教程尝试的过程中有错误或问题,可以上面询问讨论,或者评论区留言 如果教程有什么问题,请帮忙纠正,持续更新(部分控制插件…

Android开发编程从入门到精通,安卓技术从初级到高级全套教学

一、教程描述 本套教程基于JDK1.8版本,教学内容主要有,1、环境搭建,UI布局,基础UI组件,高级UI组件,通知,自定义组件,样式主题;2、四大组件,Intent&#xff0…

数据库的连接

连接数据库 我们使用WinR输入cmd打开运行窗口 输入:sqlplus并回车 输入用户名和密码,我用的是Scott,密码我自己设置的123456,Scott默认的密码是tiger,回车 这种情况表示登录成功 在连接Scott成功的情况下创建一些数据,在我的资源里面有个Oracle数据基础可以下载,直接复制粘…

详解Java中的原子操作

第1章:什么是原子操作 大家好,我是小黑,面试中一个经常被提起的话题就是“原子操作”。那么,到底什么是原子操作呢?在编程里,当咱们谈论“原子操作”时,其实是指那些在执行过程中不会被线程调度…

59.网游逆向分析与插件开发-游戏增加自动化助手接口-文字资源读取类的C++还原

内容来源于:易道云信息技术研究院VIP课 上一个内容:游戏菜单文字资源读取的逆向分析-CSDN博客 码云地址(master分支):https://gitee.com/dye_your_fingers/sro_-ex.git 码云版本号:55358fb135a0c821d8e8…

AI实景无人直播创业项目:开启自动直播新时代,一部手机即可实现增长

在当今社会,直播已经成为了人们日常生活中不可或缺的一部分。无论是商家推广产品、明星互动粉丝还是普通人分享生活,直播已经渗透到了各行各业。然而,传统直播方式存在着一些不足之处,如需现场主持人操作、高昂的费用等。近年来&a…

C++多态性——(5)运算符重载(第二节)

归纳编程学习的感悟, 记录奋斗路上的点滴, 希望能帮到一样刻苦的你! 如有不足欢迎指正! 共同学习交流! 🌎欢迎各位→点赞 👍 收藏⭐ 留言​📝 身先才能率人,律己才能服人…

Windows重装升级Win11系统后 恢复Mysql数据

背景 因为之前电脑硬盘出现问题,换了盘重装了系统,项目的数据库全部没了,还好之前的Mysql是安装在的D盘里,还有留存文件 解决办法 1.设置环境变量 我的路径是 D:\SoftWare\Application\mysql-5.7.35-winx64 此电脑右键属性 …

简单 Web Server 程序的设计与实现 (2024)

1.题目描述 Web 服务是 Internet 最方便与受用户欢迎的服务类型,它的影响力也远远超出了专业技术范畴, 已广泛应用于电子商务、远程教育、远程医疗与信息服务等领域,并且有继续扩大的趋势。目前很多 的 Internet 应用都是基于 Web 技术的&…