当前位置: 首页 > news >正文

Spring代理模式——静态代理和动态代理

在这里插入图片描述

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。
🍎个人主页:Java Fans的博客
🍊个人信条:不迁怒,不贰过。小知识,大智慧。
💞当前专栏:SSM 框架从入门到精通
✨特色专栏:国学周更-心性养成之路
🥭本文内容:Spring代理模式——静态代理和动态代理

文章目录

    • 代理模式
    • 1、静态代理
    • 2、动态代理

代理模式

在学习 AOP 之前,我们先来了解下代理模式, 代理模式分为静态代理以及动态代理,属于23中设计模式之一。 AOP 的底层机制就是动态代理

在这里插入图片描述
作用:

通过代理类为原始类增加额外的功能

1、静态代理

1)案例展示

【1】定义一个 Teacher 接口,接口中定义两个方法:teachOnLineteachOffLine

package cn.gc.spring03.interfce;public interface Teacher {String teachOnLine(String course);String teachOffLine(String course);
}

【2】定义一个实现 Teacher 接口的 TeacherA 实现类,代码如下:

package cn.gc.spring03.interfce.impl;import cn.gc.spring03.interfce.Teacher;public class TeacherA implements Teacher {@Overridepublic String teachOnLine(String course) {System.out.println("开始"+course+"课程线上教学");return course+"课程线上教学";}@Overridepublic String teachOffLine(String course) {System.out.println("开始"+course+"课程线下教学");return course+"课程线下教学";}
}

【3】现在我们要在两个方法中的 开始课程教学 的前后添加上下课铃声的功能,此时我们再定义一个实现 Teacher 接口的静态代理类 TeacherAStaticProxy,代码如下:

package cn.gc.spring03.proxy;import cn.gc.spring03.interfce.Teacher;
import cn.gc.spring03.interfce.impl.TeacherA;public class TeacherAStaticProxy implements Teacher {TeacherA teacherA=new TeacherA();@Overridepublic String teachOnLine(String course) {System.out.println(course+"课程上课时间到了");String s = teacherA.teachOnLine(course);System.out.println(course+"课程下课时间到了");return s;}@Overridepublic String teachOffLine(String course) {System.out.println(course+"课程上课时间到了");String s = teacherA.teachOffLine(course);System.out.println(course+"课程下课时间到了");return s;}
}

【4】运行效果如下

在这里插入图片描述

2)静态代理优缺点

(1)优点 :在不修改目标对象的功能前提下,能通过代理对象对目标功能扩展;可以使得真实角色更加纯粹,不再去关注一些公共的事情;公共的业务由代理来完成,实现了业务的分工。
(2)缺点 :因为代理对象需要与目标对象实现一样的接口,所以会很多代理类 ,一旦接口增加方法,目标对象与代理对象都要维护,工作量变大,开发效率降低。

3)开发代理对象的原则

  • 代理对象和目标对象实现相同的接口

  • 代理对象依赖于目标对象

2、动态代理

在不改变原来的代码的情况下,实现了对原有功能的增强,这是 AOP 中最核心的思想。

AOP:纵向开发,横向开发

在这里插入图片描述

1)简介

动态代理的角色和静态代理的一样。但是动态代理的代理类是动态生成的,而静态代理的代理类是提前写好的。

动态代理分为两类,一类是基于接口动态代理(JDK,一类是基于类的动态代理(CGLib

2)基于接口动态代理(JDK

程序运行的过程中,通过 JDK 提供代理技术动态的为某个类产生动态代理对象的过程。

开发代理对象的原则:

  • 代理对象,不需要实现接口,但是目标对象要实现接口,否则不能用JDK动态代理。
  • 代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象。
  • 动态代理也叫做 :JDK代理、接口代理。

JDK 的动态代理需要了解两个类:

  • 核心 : InvocationHandler (调用处理程序) 和 Proxy (代理)

在这里插入图片描述

实现步骤:在上面案例的基础上实现。

创建一个基于 JDK 的代理工具类 DynamicProxy 类:

package cn.gc.spring03.proxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;/** 基于JDK的代理工具类*/
public class DynamicProxy {//被代理对象private Object target;public DynamicProxy(Object obj) {this.target = obj;}//生成代理对象public Object getProxy() {//获取类加载器ClassLoader classLoader = target.getClass().getClassLoader();//获取被代理对象实现的所有接口Class<?>[] interfaces = target.getClass().getInterfaces();//增强功能代码编写的位置InvocationHandler invocationHandler = new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 增强的功能System.out.println(args[0] + "课程上课时间到了");// 通过反射执行目标方法Object invoke = method.invoke(target, args);// 增强的功能System.out.println(args[0] + "课程下课时间到了");return invoke;}};Object o = Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);return o;}
}

测试:

    @Testpublic void test02() {Teacher teacher  = new TeacherA();DynamicProxy dynamicProxy = new DynamicProxy(teacher);Teacher teacherProxy = (Teacher) dynamicProxy.getProxy();teacherProxy.teachOnLine("Java");System.out.println("______________________");teacherProxy.teachOnLine("C++");}

运行效果:

在这里插入图片描述

3)基于类的动态代理(CGLib

开发代理对象的原则:

  • 代理对象无需和原始类对象实现相同的接口

  • 代理对象和原始类对象要存在父子类关系

CGLib 的动态代理需要了解两个类:

  • 核心 : EnhancerMethodInterceptor

实现步骤

创建一个 Aoo 类:

package cn.gc.spring03.interfce.impl;public class Aoo {public String test01(String info){System.out.println("Aoo中的test01方法被调用。");return info;}
}

创建一个基于 CGLib 的代理工具类 CglibProxy 类:

package cn.gc.spring03.proxy;import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class CglibProxy {private Object target;public CglibProxy(Object obj){this.target=obj;}public Object getProxy(){Enhancer enhancer=new Enhancer();//设置类加载器enhancer.setClassLoader(CglibProxy.class.getClassLoader());//设置被代理对象enhancer.setSuperclass(target.getClass());//增强功能代码编写的位置MethodInterceptor methodInterceptor=new MethodInterceptor() {@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println("-------------cglib log--------------");Object invoke = method.invoke(target, objects);System.out.println("-------------cglib log--------------");return invoke;}};enhancer.setCallback(methodInterceptor);//代理对象Object o = enhancer.create();return o;}
}

测试:

    @Testpublic void test03() {Aoo aoo=new Aoo();CglibProxy cglibProxy = new CglibProxy(aoo);Aoo proxy = (Aoo) cglibProxy.getProxy();String info = proxy.test01("java");System.out.println("info = " + info);}

运行效果:

在这里插入图片描述

4)动态代理的优势

  1. 可以使得真实角色更加纯粹,不再去关注一些公共的事情。
  2. 公共的业务由代理来完成,实现了业务的分工。
  3. 公共业务发生扩展时变得更加集中和方便。
  4. 一个动态代理,一般代理某一类业务。
  5. 一个动态代理可以代理多个类,代理的是接口。

在这里插入图片描述


  码文不易,本篇文章就介绍到这里,如果想要学习更多Java系列知识点击关注博主,博主带你零基础学习Java知识。与此同时,对于日常生活有困扰的朋友,欢迎阅读我的第四栏目:《国学周更—心性养成之路》,学习技术的同时,我们也注重了心性的养成。

在这里插入图片描述

相关文章:

Spring代理模式——静态代理和动态代理

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

Anaconda和PyCharm的一些安装问题和命令

今天更新了Windows上的Anaconda到2.3.2&#xff0c;PyCharm到2022.3。 ——发现是纯纯的犯贱orz。出了一堆问题。在这里记录一下供后来者参考。 Anaconda安装 将.\anaconda3\Scripts 和.\anaconda3\Library\bin添加到系统环境变量中。 新建环境的目录在.\anaconda3\envs下 N…...

sql优化建议

对查询进行优化&#xff0c;应尽量避免全表扫描&#xff0c;首先应考虑在 where 及 order by 涉及的列上建立索引。 应尽量避免在 where 子句中使用!或<>操作符&#xff0c;否则将引擎放弃使用索引而进行全表扫描。 应尽量避免在 where 子句中对字段进行 null 值判断&a…...

google hacker语句

哎&#xff0c;我就是沾边&#xff0c;就是不打实战(&#xffe3;o&#xffe3;) . z Z 文章目录前言一、什么是谷歌Docker&#xff1f;二、受欢迎的谷歌docker语句谷歌docker的例子日志文件易受攻击的 Web 服务器打开 FTP 服务器SSH私钥电子邮件列表实时摄像机MP3、电影和 PDF…...

Spring AOP

Spring AOP 文章目录Spring AOP1.概念1.面向切面编程2.AOP的目的3.AOP实现的分类4.AOP 术语2. Spring AOP的特性1.能力与目标2.AOP机制1.理解SpringAOP的代理2.AOP代理类的自调用代码的粒度如何让自调用走代理&#xff1f;3.Enabling AspectJ Support3. 定义切面与切点1. 声明切…...

【消费战略方法论】认识消费者的恒常原理(一):消费者稳态平衡原理

“消费战略”是塔望咨询基于大量的战略与营销实践经验结合心理学、经济学、传播学等相关专业学科的知识应用进行提炼与创造形成的战略方法体系。消费战略强调以消费者为导向&#xff0c;进行企业、品牌战略、品牌营销的制订和落地&#xff0c;企业经营的每个环节和输出的每个动…...

python居然能语音控制电脑壁纸切换,只需60行代码

前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 家在日常的电脑使用中&#xff0c;都会有自己喜爱类型的桌面 单纯的桌面有时候会让人觉得单调 今天&#xff0c;就由我带领大家只用60行代码打造一款语音壁纸切换器程序&#xff0c; 让大家能够通过语音的方式来控制电脑去…...

内存泄露定位手段(c语言hook malloc相关方式)

如何确定有内存泄露问题&#xff0c;如何定位到内存泄露位置&#xff0c;如何写一个内存泄漏检测工具&#xff1f; 1&#xff1a;概述 内存泄露本质&#xff1a;其实就是申请调用malloc/new&#xff0c;但是释放调用free/delete有遗漏&#xff0c;或者重复释放的问题。 内存…...

STM32 CAN波特率计算

STM32 CAN波特率计算简介CAN总线收发&#xff0c;中断方式接收配置代码部分reference简介 CAN通信帧共分为数据帧、远程帧、错误帧、过载帧和帧间隔&#xff0c;本文这里以数据帧为例。 显性电平对应逻辑0&#xff0c;CAN_H和CAN_L之差为2.5V左右。而隐性电平对应逻辑1&#x…...

C/C++ 中#define 的妙用,让代码更美一些

C/C 中#define 的妙用&#xff0c;让代码更美一些 flyfish 1 数值类型输出易读的字符串形式 例如使用enum定义一些错误值&#xff0c;想要将数值类型的错误&#xff0c;输出易读的字符串形式 重要的一句代码 #define MAKE_PAIR(val) std::make_pair(val, #val)可以看到 #va…...

Linux文件系统操作与磁盘管理

查看磁盘和目录的容量 使用 df 命令查看磁盘的容量 df在实验楼的环境中你将看到如下的输出内容&#xff1a; 但在实际的物理主机上会更像这样&#xff1a; 物理主机上的 /dev/sda2 是对应着主机硬盘的分区&#xff0c;后面的数字表示分区号&#xff0c;数字前面的字母 a 表示…...

【Python】批量采集原神表情包~

嗨害大家好鸭~我是小熊猫(✿◡‿◡) 最近迷上了原神&#xff0c; 不自觉中就很喜欢保存广大旅行者制作的表情包~ 真的很有意思诶~ 源码资料电子书:点击此处跳转文末名片获取 一个个保存的话&#xff0c;好像效率很低嘛… 那我就发挥我小熊猫的老本行直接给把他们全部采集下…...

C语言基本语法注释类型关键字

C 基本语法 标识符 给变量所取的名字叫变量名&#xff0c;定义变量的名字需要遵循标识符的命名规则。 标识符是用来标识变量、符号常量、数组、函数、文件等名字的有效字符序列。 标识符的命名规则&#xff1a; 1.只能由字母、数字和下划线组成&#xff08;例如&#xff1a…...

【C ++】C++入门知识(二)

C入门&#xff08;二&#xff09; 作者&#xff1a;小卢 专栏&#xff1a;《C》 喜欢的话&#xff1a;世间因为少年的挺身而出&#xff0c;而更加瑰丽。 ——《人民日报》 1.引用 1.1.引用的概念及应用 引用&#xff08;&&#xff09; 引用不是新定义一个变量&#xff0…...

qt qchart学习

Qt Charts主要由QChartView、QChart、QLegend图例、坐标轴(由QAbstractAxis子类实现)、**数据源(由QAbstractSeries子类实现)**等组成使用QChart的前期准备1. Qt5.9及以上版本&#xff1b;2. .pro文件中添加QT charts3. 在使用QChart的各个控件之前&#xff0c;引用头文件并必…...

手工布署 java 项目

新建一个java springboot项目 maven 这是一个非常简易的 springBoot 的项目 使用 maven 的 package 工具进行打包 把包上传到 linux 的机器上&#xff0c; 确保 linux 机器上安装了 java jdk工具&#xff0c; 并且配置好了 JAVA_HOME 注意&#xff0c;helloworld 默认的是要使…...

《设计模式》观察者模式

《设计模式》观察者模式 观察者模式是一种行为型设计模式&#xff0c;它定义了一种一对多的依赖关系&#xff0c;让多个观察者对象可以同时监听和相应被观察者对象的状态变化&#xff0c;以达到解耦和复用的目的。观察者模式的优点如下&#xff1a; 解耦&#xff1a;观察者模…...

基于SpringBoot的外卖项目(详细开发过程)

基于SpringBootMyBatisPlus的外卖项目1、软件开发整体介绍软件开发流程角色分工2、外卖项目介绍项目介绍产品展示后台系统管理移动端技术选型功能结构角色3、开发环境的搭建开发环境说明建库建表Maven项目搭建项目的目录结构pom.xmlapplication.ymlReggieApplication启动类配置…...

ChatGPT 研发传言席卷互联网公司,这会是一门好生意吗?

ChatGPT&#xff08;也称GPT-3&#xff09;是一种基于人工智能的自然语言生成模型&#xff0c;由OpenAI团队开发。它是GPT系列模型的最新版本&#xff0c;于2020年6月发布。ChatGPT的由来GPT-1是在2018年发布的第一个版本&#xff0c;使用了12亿个参数。随后&#xff0c;GPT-2在…...

获取servlet转发和响应重定向的方式是什么?

&#xff08;1&#xff09; 重定向和转发的区别 1&#xff09;重定向是浏览器发送请求并受到响应以后再次向一个新地址发请求&#xff1b;转发是服务器受到请求后为了完成响应转到一个新的地址。 2&#xff09;重定向中有两次请求对象&#xff0c;不共享数据&#xff1b;转发…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

Unity UGUI Button事件流程

场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...

es6+和css3新增的特性有哪些

一&#xff1a;ECMAScript 新特性&#xff08;ES6&#xff09; ES6 (2015) - 革命性更新 1&#xff0c;记住的方法&#xff0c;从一个方法里面用到了哪些技术 1&#xff0c;let /const块级作用域声明2&#xff0c;**默认参数**&#xff1a;函数参数可以设置默认值。3&#x…...

绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化

iOS 应用的发布流程一直是开发链路中最“苹果味”的环节&#xff1a;强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说&#xff0c;这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发&#xff08;例如 Flutter、React Na…...