Spring5应用之AOP动态代理开发

news2024/11/18 17:25:36

作者简介:☕️大家好,我是Aomsir,一个爱折腾的开发者!
个人主页:Aomsir_Spring5应用专栏,Netty应用专栏,RPC应用专栏-CSDN博客
当前专栏:Spring5应用专栏_Aomsir的博客-CSDN博客

文章目录

  • 前言
  • 何为动态代理?
  • 开发编码
    • 测试结果
  • 动态代理细节分析
    • Spring创建的动态代理类在什么地方?
    • 什么叫动态字节码技术?
  • 总结
  • 参考文献

前言

在上一篇文章: 《Spring5应用之静态代理开发》中,我们详细地探讨了静态代理开发所面临的诸多问题,如代码冗余、维护困难等问题。为了克服这些问题,本文将引导大家深入了解Spring5的动态代理开发

何为动态代理?

通过代理类为原始类添加附加功能,这样做的优点是有利于原始类的维护与扩展。其作用和优势与静态代理相同。然而,动态代理与静态代理最明显的不同在于它们的开发流程和底层实现方式

开发编码

  • 引入必要的动态代理相关jar包:确保项目中有所需的依赖库,以支持动态代理的实现。
  • 创建并配置原始对象(目标对象):创建需要被代理的原始对象,并将其注入到Spring容器中。
  • 实现MethodBeforeAdvice接口:此接口用于在目标方法调用之前添加额外的功能。完成此实现后,也应将其注入到Spring容器中。
  • 定义切入点:切入点指定在哪些特定的原始方法上需要添加额外的功能。
  • 进行配置整合:将原始对象、增强功能及切入点配置到Spring中,确保它们可以正确地协同工作。
  • 编写测试类:为了验证动态代理的效果,可以编写测试类并通过原始对象的ID从容器中获取代理对象,进而调用相关方法进行验证
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>5.1.14.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.8.8</version>
</dependency>

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.3</version>
</dependency>
public class Before implements MethodBeforeAdvice {

    private static final Logger log = LoggerFactory.getLogger(Before.class);

    /**
     * 把需要在原始方法执行之前的功能,书写在before方法中
     * @param method 原始方法
     * @param objects 原始方法的参数
     * @param o 原始方法所在的对象
     * @throws Throwable 异常
     */
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        log.info("-------method before advice log-------");
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="userService" class="com.aomsir.basic.proxy.service.impl.UserServiceImpl" />
    <bean id="before" class="com.aomsir.basic.proxy.dynamic.Before" />

    <aop:config>
        <!--定义切入点,将额外方法加在所有类的方法上-->
        <aop:pointcut id="pc" expression="execution(* * (..))"/>

        <!--组装,将额外功能与切入点进行组装整合-->
        <aop:advisor advice-ref="before" pointcut-ref="pc" />
    </aop:config>
</beans>
public class TestProxy {
    @Test
    public void test2() {
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

        UserService userService = (UserService) ctx.getBean("userService");

        userService.login("Aomsir", "123456");
        userService.register(new User());
    }
}

测试结果

从图1的测试结果中,我们可以清晰地观察到在UserService中的两个方法上都已经成功添加了额外的功能。这证明了我们的动态代理配置起到了预期的作用。

进一步地,从图2中我们可以看到一个Debug的方法调用过程。仔细观察后,可以发现通过原始类型id获取的对象已不再是初始的原始对象。相反,它现在是一个经过整合和配置后的代理对象,这进一步证实了动态代理的实际效果
在这里插入图片描述
在这里插入图片描述

动态代理细节分析

Spring创建的动态代理类在什么地方?

通过前述的编码流程和测试结果展示,我们可以清晰地了解到Spring已经为我们自动完成了目标类与额外功能的整合工作。但这时候一个问题出现了:那动态代理类存放在何处?在我们的程序中并没有明确地看到这个类。

其秘密在于,Spring框架利用了动态字节码技术。当程序运行时,Spring会在JVM内部实时地生成这个动态代理类。由于这个类仅仅是在运行时动态创建的,所以当程序执行结束后,它将随着JVM的关闭而消失

什么叫动态字节码技术?

我们已经了解到,Spring通过动态字节码技术来创建动态代理类。但动态字节码技术到底是什么?

当Java程序运行时,是由JVM加载类的字节码文件(.class)来执行的。而动态字节码技术,正是利用一些第三方框架如ASM、javassist、Cglib等来实现的。这些框架能够帮助我们直接在JVM内部生成动态的字节码(.class),进而创建相应的代理对象,而无需在文件系统中实际生成一个物理文件

当JVM进程结束后,这些动态生成的字节码同样会被清除。这意味着,与静态代理不同,动态代理不会产生实际的类文件。因此,它避免了因为类文件数量众多而可能给项目管理带来的麻烦。

总结

在今天的《Spring5之AOP动态代理开发》主题中,我并没有进行深入细致的AOP分析。不过,不用担心,接下来的系列文章中,我会逐步带领大家深入探讨Spring AOP的各个知识点,包括切入点表达式、MethodInterceptor、动态代理的底层实现原理等内容

参考文献

  • 孙哥孙帅suns说Spring5~学不会Spring? 因为你没找对人
  • Spring官方文档

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

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

相关文章

使用Packet Tracer了解网络模型及Lab3 - 2

显示TCP/IP协议套件的元素 这些额外的条目在 TCP/IP 套件中扮演着各种角色。如果列出了地址解析协议 &#xff08;ARP&#xff09;&#xff0c;它将搜索 MAC 地址。DNS 负责将名称&#xff08;例如 www.osi.local&#xff09;转换为 IP 地址。其他 TCP 事件负责连接、商定通信…

DETR纯代码分享(九)transformer.py

一、定义DETR Transformer用于DETR模型 """ DETR Transformer class.Copy-paste from torch.nn.Transformer with modifications:* positional encodings are passed in MHattention* extra LN at the end of encoder is removed* decoder returns a stack of …

趣解设计模式之《当代毕加索小王》

〇、小故事 小王最近对画油画非常的感兴趣&#xff0c;尤其是当他参观完毕加索画展之后&#xff0c;更觉得自己有画画天赋了&#xff0c;“这画我自己也能画啊&#xff01;这以后一幅画随随便便买它2、3个亿&#xff0c;这不发财了&#xff01;”于是&#xff0c;他就开始着手…

Java——》IO

推荐链接&#xff1a; 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Kafka】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 总结——》【Linux】 总结——》【MongoD…

12KM02E-V0002 3EGM030300R0002 模块化和加固的边缘计算加速

12KM02E-V0002 3EGM030300R0002 模块化和加固的边缘计算加速 随着边缘人工智能解决方案的兴起&#xff0c;对实时洞察和自主决策的需求显著增长。这也带来了对变革性技术的高度需求&#xff0c;这些技术可以在坚固的边缘支持和提供最佳性能。为了应对技术革命&#xff0c;Prem…

C#开发 降.NET版本问题解决笔记

C#开发 降.NET版本问题记录 以下都是我在使用.NET4.7.2版本开发控件完成后又将控件代码降位使用.NET4.5时所遇到的问题&#xff0c;和解决方式 Struct构造函数&#xff1a;“必须将字段完全分配&#xff0c;然后控制权才能返回给调用者。” 原始的代码和错误如下&#xff1a…

PMP证书的价值如何?

2022年开始&#xff0c;PMP考试启用了新考纲&#xff0c;不光考试内容进行了大刀阔斧的改革&#xff0c;出题方式也进行了更新。除原有的PMBOK6和PMBOK7主考教材外&#xff0c;还增加了一本《敏捷实践指南》。 别小看新加的这本书&#xff0c;它虽然与PMBOK代表的预测法属于完…

史上最强,从0到1接口自动化测试落地实施,资深老鸟整理...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 为什么要做接口测…

Python 编程基础 | 第一章-预备知识 | 1.3、运行方式

一、Python运行代码 可以使用三种方式运行Python&#xff0c;如下&#xff1a; 1、交互式 通过命令行窗口进入 Python 并开始在交互式解释器中开始编写 Python 代码 2、命令行脚本 可以把代码放到文件中&#xff0c;通过python 文件名.py命令执行代码&#xff0c;如下&#xff…

智慧公厕云管理平台:筑牢云上“城市公共厕所一张网”

在现代城市中&#xff0c;公共厕所是人们日常生活中不可或缺的一部分。然而&#xff0c;过去的公共厕所管理方式往往效率低下&#xff0c;维护困难&#xff0c;给市民带来了不便。为了解决这一问题&#xff0c;智慧公厕应运而生&#xff0c;赋予传统公共厕所智慧化的管理效能。…

论文精读:Feature Pyramid Networks for Object Detection

文章目录 1. 摘要1.1 背景1.2 提出新方法1.3 贡献 2. 引言2.1 提出问题2.2 叙述Feature pyramid2.3 叙述深度卷积网络2.4 Feature pyramid的局限2.5 使用deep ConvNet计算多尺度特征的方式2.6 提出我们的方法2.7 贡献 3. 相关工作3.1 手工工程特征和早期神经网络3.2 深度卷积目…

工业RFID识别设备可以在哪些行业应用?

工业识别设备主要是用于工业领域的RFID读写设备&#xff0c;它可以在产线、工厂、仓储物流等领域应用&#xff0c;非接触的实时读取标签信息&#xff0c;并且将读取的信息上传到电脑信息管理系统中。 工业RFID识别设备可以在哪些行业应用? 1、汽车行业 汽车制造业的产品结构复…

简单的springboot整合minio完成上传查询等

1、本地下载minio brew install minio/stable/minio2、下载结果 3、启动minio /opt/homebrew/opt/minio/bin/minio server --config-dir/opt/homebrew/etc/minio --address:9000 /opt/homebrew/var/minio4、启动完成 5、web页面 账号密码&#xff1a; minioadmin 登陆完成…

快递查询方法分享:如何批量查询并筛选大量超时件?

快递批量查询工具推荐&#xff1a;一键筛选超时件&#xff0c;高效管理物流信息&#xff01; 在现代快节奏的生活中&#xff0c;快递已成为人们日常不可或缺的一部分。然而&#xff0c;随着快递量的不断增加&#xff0c;如何高效地查询和管理快递成了一个问题。今天&#xff0…

Optimus—多学科仿真集成与优化设计平台

Optimus是比利时Noesis Solutions公司专注研发的一款多学科仿真集成与优化设计软件产品。通过Optimus平台&#xff0c;可管理多学科的仿真流程及数据&#xff0c;自动显示和探索设计空间&#xff0c;进行产品设计过程中的自动性能优化&#xff0c;实现多学科、多指标参数的均衡…

【三相有源电力滤波器】使用同步参考系控制的三相有源功率滤波器(Simulink)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

ElementUI实现增删改功能以及表单验证

目录 前言 BookList.vue action.js 展示效果 前言 本篇还是在之前的基础上&#xff0c;继续完善功能。上一篇完成了数据表格的查询&#xff0c;这一篇完善增删改&#xff0c;以及表单验证。 BookList.vue <template><div class"books" style"pa…

veImageX 演进之路:Web 图片加载提速50%

背景说明 火山引擎veImageX演进之路主要介绍了veImageX在字节内部从2012年随着字节成长过程中逐步演进的过程&#xff0c;演进中包括V1、V2、V3版本并最终面向行业输出&#xff1b;整个演进过程中包括服务端、客户端、网络库、业务场景与优化等多个角度介绍在图像处理压缩、省成…

如何快速轻松自动添加微信好友?

有些客需要换新的微信号&#xff0c;想把以前微信号上的好友全部加回来&#xff0c;但是因为微信系统的规定&#xff0c;频繁加好友容易被封号&#xff0c;而且手动添加好友太费时费力&#xff0c;还要控制加好友的间隔时间。那么有没有什么方法可以快速轻松自动添加好友呢&…

郁金香2021年游戏辅助技术中级班(一)

郁金香2021年游戏辅助技术中级班&#xff08;一&#xff09; 用代码读取utf8名字字节数组搜索UTF-8字符串 用CE和xdbg分析对象名字从LUA函数的角度进行分析复习怪物名字偏移 用CE和xdbg分析对象数组认识虚函数表分析对象数组 分析对象数组链表部分链表的定义链表的数据在内存里…