【Java EE进阶 --- SpringBoot】AOP原理

【Java EE进阶 --- SpringBoot】AOP原理


🚀 欢迎来到我的ZEEKLOG博客:Optimistic _ chen
一名热爱技术与分享的全栈开发者,在这里记录成长,专注分享编程技术与实战经验,助力你的技术成长之路,与你共同进步!


🚀我的专栏推荐

专栏内容特色适合人群
🔥C语言从入门到精通系统讲解基础语法、指针、内存管理、项目实战零基础新手、考研党、复习
🔥Java基础语法系统解释了基础语法、类与对象、继承Java初学者
🔥Java核心技术面向对象、集合框架、多线程、网络编程、新特性解析有一定语法基础的开发者
🔥Java EE 进阶实战Servlet、JSP、SpringBoot、MyBatis、项目案例拆解想快速入门Java Web开发的同学
🔥Java数据结构与算法图解数据结构、LeetCode刷题解析、大厂面试算法题面试备战、算法爱好者、计算机专业学生

🚀我的承诺:
✅ 文章配套代码:每篇技术文章都提供完整的可运行代码示例

✅ 持续更新:专栏内容定期更新,紧跟技术趋势

✅ 答疑交流:欢迎在文章评论区留言讨论,我会及时回复(支持互粉)


🚀 关注我,解锁更多技术干货!
⏳ 每天进步一点点,未来惊艳所有人!✍️ 持续更新中,记得⭐
收藏关注⭐不迷路 ✨

📌 标签:#技术博客#编程学习#Java#C语言#算法#程序员

文章目录

上篇博客讲到Spring AOP的应用,这篇博客带你了解Spring是如何实现AOP的?

代理模式

代理模式,也叫做委托模式:为其他对象提供一种代理以控制对这个对象的访问。

作用:提供一个代理类,让程序员调用目标方法时,不再是直接对目标方法进行调用,而是通过代理类间接调用。

在这里插入图片描述


生活中的例子:

  • 律师:法庭上,代理辩护人进行辩护
  • 房产中介:房屋进行租凭时,房东会把房屋授权给中介,由中介代理租凭事务

代理模式中的主要角色

  1. Subject:业务接口类,可以是抽象类(调用方)
  2. RealSubject:业务实现类,具体业务逻辑实现,也就是目标方法(被代理对象)
  3. Proxy: 代理类,RealSubject的代理

客户端角度出发,它调用Subject接口定义的目标方法,并不关心这个方法的实现逻辑。
代理模式结构出发,Proxy(代理类)没有实现目标方法,但是它可以调用目标方法并且在不修改目标方法的前提下,增加其他逻辑(功能),使得整个代码的可扩展性大大提高

在这里插入图片描述

静态代理

静态代理:由程序员创建代理类或特定工具自动生成源码在对其编译,在程序运行前代理类的.class文件就已经存在了。也就是在租房之前,中介就已经做好了准备工作,就等客户来“调用”了。

我们通过代码来观察一下:

定义业务接口(定义出租房子):

publicinterfaceHouseSubject{voidrentHouse();}

实现接口(房东出租房子):

publicclassRealHouseSubjectimplementsHouseSubject{@OverridepublicvoidrentHouse(){System,out.println("我是房东,我要出租房子");}}

代理类(中介,代理房东出租房子)

publicclassHouseProxyimplementsHouseSubject{privateHouseSubject houseSubject;publicHouseProxy(HouseSubject houseSubject){this.houseSubject = houseSubject;}@OverridepublicvoidrentHouse(){System,out.println("我是中介,开始代理"); houseSubject.rentHouse();System,out.println("我是中介,结束代理");}}

客户端使用方法:

publicclassMain{publicstaticvoidmain(String[] args){HouseSubject subject=newRealHouseSubject();//创建代理类HouseProxy proxy=newHouseProxy(subject);//通过代理类访问目标方法 proxy.rentHouse();}}

从运行结果发现,虽然静态代理都实现了目标方法的代理,但是方法的增强都是手动完成,很死板。如果以后需要增加其他接口(功能),还需要对业务实现类新增代理类。

其实这里我有一个疑问,为什么不把所有方法都写在一个类里面,这样就只有一个代理类了。
这样设计会反应出一些原则问题,比如违反一个职责原则:一个类只能表现出它本身职责;代理逻辑难以复用:代理模式的主要职责受到限制,因为不同方法需要不同的增强逻辑,不能都混在一个类里面。(比如要其中一个方法计算耗时,但是另一个方法需要事务管理,最好的方法就是动态代理+职责拆分

动态代理

动态代理:在程序运⾏时,运⽤反射机制动态创建⽽成

我们不需要针对每个对象都单独创建一个代理类,⽽是把这个创建代理对象的⼯作推迟到程序运⾏时由JVM来实现.也就是说动态代理在程序运⾏时,根据需要动态创建⽣成。(有点像懒汉模式)
Java对动态代理进行了实现,并提供了一些API,常见的实现有:

  • JDK动态代理
  • CGLIB动态代理

JDK动态代理

定义接口及其实现类(HouseSubject和RealHouseSubject)

publicinterfaceHouseSubject{voidrentHouse();}publicclassRealHouseSubjectimplementsHouseSubject{@OverridepublicvoidrentHouse(){System,out.println("我是房东,我要出租房子");}}

自定义InvocationHandler并重写invoke方法,在invoke方法中调用目标方法(被代理方法)并自定义一些处理逻辑

importjava.lang.reflect.InvocationHandler;importjava.lang.reflect.Method;publicclassJDKInvocationHandlerimplementsInvocationHandler{//目标对象就是代理对象privateObject target;publicJDKInvocationHandler(Object target){this.target=target;}/** * @param proxy 代理对象 * @param method 目标方法 * @param args 方法对应的参数 * @return * @throws Throwable */@OverridepublicObjectinvoke(Object proxy,Method method,Object[] args)throwsThrowable{//代理增强内容System.out.println("我是中介,开始代理");//通过反射调用被代理的方法Object retVal=method.invoke(target,args);System.out.println("我是中介,结束代理");return retVal;}}

InvocationHandler接⼝是Java动态代理的关键接⼝之⼀,它定义了⼀个单⼀⽅法invoke(),⽤于处理被代理对象的⽅法调⽤。通过InvocationHandler接口,对被代理对象的方法进行功能增强。

客户端创建一个代理对象并使用

publicclassMain{publicstaticvoidmain(String[] args){HouseSubject target=newRealHouseSubject();//创建⼀个代理类:通过被代理类、被代理实现的接⼝、⽅法调⽤处理器来创建HouseSubject proxy =(HouseSubject)Proxy.newProxyInstance( target.getClass().getClassLoader(),//使用目标类的类加载器newClass[]{HouseSubject.class},//代理要实现的接口newJDKInvocationHandler(target)//方法调用代理类); proxy.rentHouse();}}

整个流程是:

  1. JVM在运行时动态创建一个新的类(相当于静态代理的手动实现接口),这个类实现了HouseSubject接口(相当于中介的”工作证“,证明中介可以提供出租房子)
  2. 客户端调用代理对象(中介)的rentHouse()方法
  3. 进入动态生成的rentHouse()方法(客户端租房请求)
  4. 动态生成类将调用转发给代理类(中介)
  5. 进入代理类(中介)的invoke()方法
  6. 执行前置增强(开始代理)
  7. 通过反射调用目标方法method.invkoe()(中介联系房东)
  8. 进入RealHouseSubject的rentHouse()方法(出租房子)
  9. 执行后置增强功能(结束代理)
  10. 返回结果给InvocationHandler (中介完成任务)
  11. 返回结果给动态生成类 (中介向客户反馈结果)
  12. 返回客户端调用者(客户租到房子)
在这里插入图片描述


总结:JVM为接口中的每个方法生成相同的调用模板,所有的方法调用都通过invoke这一个入口,新增方法时 代理逻辑自动生效(method.invoke(target, args)调用实际方法),无需修改代码。

CGLIB动态代理

CGLIB是开源项目,使用需要添加相关依赖

<dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.3.0</version></dependency>

接口及其实现类同上:

自定义MethodeInterceptor 并重写intercept方法(与invoke类似)

importorg.springframework.cglib.proxy.MethodInterceptor;importorg.springframework.cglib.proxy.MethodProxy;importjava.lang.reflect.Method;publicclassCGLIBInterceptorimplementsMethodInterceptor{//目标对象(中介)privateObject target;publicCGLIBInterceptor(){this.target=target;}/** * @param obj 被代理的对象(房东) * @param method 目标方法(增强方法) * @param args 方法参数 * @param proxy 代理对象(中介)调用原始方法 * @return * @throws Throwable */@OverridepublicObjectintercept(Object obj,Method method,Object[] args,MethodProxy proxy)throwsThrowable{//代理增强内容System.out.println("我是中介,开始代理");//通过反射调用被代理的方法Object retVal=method.invoke(target,args);System.out.println("我是中介,结束代理");return retVal;}}

客户端创建代理类:

publicclassDynamicMain{publicstaticvoidmain(String[] args){HouseSubject target=newRealHouseSubject();//被代理的接口 拦截的目标方法HouseSubject proxy=(HouseSubject)Enhancer.create(target.getClass(),newCGLIBInterceptor(target)); proxy.rentHouse();}}

总结

  • AOP和Ioc一样都是一种思想,AOP是对某一类事件的集中处理,Spring框架实现了AOP,称之为Spring AOP。
  • Spring AOP常⻅实现⽅式有两种:
    1.基于注解@Aspect来实现
    2.基于⾃定义注解来实现,还有⼀些更原始的⽅式:基于代理等等
  • Spring AOP是基于JDK,CGLIB动态代理实现的,运⾏时使⽤哪种⽅式与项⽬配置和代理的对象有关。

完结撒花!🎉

如果这篇博客对你有帮助,不妨点个赞支持一下吧!👍
你的鼓励是我创作的最大动力~

想获取更多干货? 欢迎关注我的专栏 → optimistic_chen
📌 收藏本文,下次需要时不迷路!

我们下期再见!💫 持续更新中……


悄悄说:点击主页有更多精彩内容哦~ 😊

Read more

文心大模型4.5系列开源测评:国产千亿MoE架构的技术突破与生态实践

文心大模型4.5系列开源测评:国产千亿MoE架构的技术突破与生态实践

2025年6月30日,百度在GitCode平台正式发布文心大模型4.5系列开源版本,这一里程碑事件标志着国产大模型技术迈入新的发展阶段。作为首个在国内开源平台首发的千亿参数级MoE模型,文心4.5不仅在架构设计上实现多模态融合与参数效率的平衡,更在开源生态建设上树立了新的标杆。本文将围绕技术架构创新、性能基准测试、部署实测体验与生态价值四个方面进行全方位深度测评。 一、开源背景与战略意义 * 发布时间:2025年6月30日 * 开源平台:GitCode(国内领先开源社区):https://ai.gitcode.com/theme/1939325484087291906 * 模型规模:涵盖0.3B到47B激活参数的完整序列 * 技术特色:MoE架构 + 多模态融合 + 高效推理 文心4.5系列的开源发布具有深远的战略意义。在全球大模型竞争日趋激烈的背景下,百度选择在国产开源平台首发,不仅展现了对中国开源生态的坚定支持,更体现了推动AI技术民主化的决心。通过提供从轻量级到大规模的完整模型矩阵,文心4.5系列满足了从边缘计算到云端部署的全场景需求,真正实现了一套架构,全场

By Ne0inhk
Flask工厂模式与蓝图设计:构建可扩展大型应用的架构之道

Flask工厂模式与蓝图设计:构建可扩展大型应用的架构之道

目录 📖 摘要 🏗️ 第一章:为什么需要工厂模式? 1.1 从单体应用到模块化架构 1.2 工厂模式的诞生 1.3 性能提升数据 🔧 第二章:Flask应用工厂深度解析 2.1 基础工厂实现 2.2 配置管理 2.3 扩展初始化顺序 🧩 第三章:蓝图模块化架构 3.1 蓝图基础 3.2 企业级蓝图结构 3.3 蓝图间通信 🚀 第四章:完整电商平台实战 4.1 项目结构 4.2 应用工厂完整实现 4.3 数据模型设计 4.4 测试策略 🚀 第五章:

By Ne0inhk
Flutter 三方库 clean_network 的鸿蒙化适配指南 - 掌握高度解耦的网络层封装技术、助力鸿蒙应用构建具备异常自愈与类型安全能力的整洁架构通讯体系

Flutter 三方库 clean_network 的鸿蒙化适配指南 - 掌握高度解耦的网络层封装技术、助力鸿蒙应用构建具备异常自愈与类型安全能力的整洁架构通讯体系

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 clean_network 的鸿蒙化适配指南 - 掌握高度解耦的网络层封装技术、助力鸿蒙应用构建具备异常自愈与类型安全能力的整洁架构通讯体系 前言 在 OpenHarmony 鸿蒙应用应对“多来源数据合并、复杂的鉴权刷新逻辑、全球化异常拦截”的工程实战中,传统的网络请求封装往往容易演变成“万能类”黑洞。如何实现网络层与业务逻辑的彻底解耦?如何让每一个 API 请求都具备标准化的成功与错误闭环(Either Pattern)?clean_network 作为一个专门为“整洁架构(Clean Architecture)”量身定制的网络增强库,旨在为鸿蒙开发者提供一套高性能、高标准且可单元测试的通讯骨架。本文将详述其在鸿蒙端的实战技法。 一、原原理分析 / 概念介绍 1.1 基础原理 clean_network 的核心逻辑是 基于

By Ne0inhk
Spring Cloud 高并发订单服务实战:从创建流程优化到 Seata 分布式事务落地(附代码 + 架构图)

Spring Cloud 高并发订单服务实战:从创建流程优化到 Seata 分布式事务落地(附代码 + 架构图)

前言         做电商或者供应链系统的同学肯定都遇到过这样的痛点:大促期间,数万用户同时下单,订单服务瞬间被打垮,出现接口超时、数据库锁等待、库存超卖;更头疼的是,订单创建需要跨订单服务、库存服务、支付服务三个模块,一旦某个环节出错,就会出现 “订单创建成功但库存没扣减” 或者 “库存扣减了但支付失败” 的一致性问题。         这些问题不是靠简单调优 JVM 或者加个缓存就能解决的,而是需要一套高并发优化体系 + 分布式事务解决方案的组合拳。         本文就以订单服务为核心场景,从实战角度出发,先讲清楚高并发下订单创建流程的核心优化点(限流、削峰、缓存、防超卖),再深入讲解 Seata 分布式事务的原理和三种模式,最后通过完整的代码案例,演示如何在 Spring Cloud 体系中落地 Seata,彻底解决跨服务的事务一致性问题。         全文都是干货,包含4 张核心 SVG 架构图、完整的代码片段、实际开发中的坑和解决方案,建议先收藏,再慢慢看。 1.

By Ne0inhk