Spring企业开发核心框架-下
五、Spring AOP面向切面编程
1、场景设定和问题复现
①准备AOP项目
项目名:Spring-aop-annotation
②声明接口
/*** + - * / 运算的标准接口!*/
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);}
③实现接口
/*** 实现计算接口,单纯添加 + - * / 实现! 掺杂其他功能!*/
public class CalculatorPureImpl implements Calculator { @Overridepublic int add(int i, int j) { int result = i + j; return result;} @Overridepublic int sub(int i, int j) { int result = i - j; return result;} @Overridepublic int mul(int i, int j) { int result = i * j; return result;} @Overridepublic int div(int i, int j) { int result = i / j; return result;}
}
④声明带日志接口实现
新需求:需要在每一个方法中,添加控制台输出,输出参数和输出计算后的返回值!
/*** 在每个方法中,输出传入的参数和计算后的返回结果!*/
public class CalculatorLogImpl implements Calculator { @Overridepublic int add(int i, int j) { System.out.println("参数是:" + i + "," + j);int result = i + j;System.out.println("方法内部 result = " + result); return result;} @Overridepublic int sub(int i, int j) { System.out.println("参数是:" + i + "," + j); int result = i - j; System.out.println("方法内部 result = " + result);return result;} @Overridepublic int mul(int i, int j) { System.out.println("参数是:" + i + "," + j); int result = i * j; System.out.println("方法内部 result = " + result); return result;} @Overridepublic int div(int i, int j) { System.out.println("参数是:" + i + "," + j); int result = i / j; System.out.println("方法内部 result = " + result); return result;}
}
⑤代码问题分析
1)代码缺陷
- 对核心业务功能有干扰,导致程序员在开发核心业务功能时分散了精力
- 附加功能代码重复,分散在各个业务功能方法中,冗余,且不方便统一维护!
2)解决问题
- 核心就是:解耦。我们需要把附加功能从业务功能代码中抽取出来。将重复的代码统一提取,并且【动态插入】到每个业务方法!
3)技术困难
- 解决问题的困难:提取重复附加功能代码到一个类中,可以实现但是如何将代码插入到各个方法中?我们不会,我们需要引用新技术!!!
2、解决技术代理模式
① 代理模式
23种设计模式中的一种,属于结构型模式。它的作用就是通过提供一个代理类,让我们在调用目标方法的时候,不再是直视对目标方法进行调用,而是通过代理类间调用。让不属于目标方法核心逻辑的代码从目标方法中剥离出来——解耦。调用目标方法时先调用代理对象的方法,减少对目标方法的调用和打扰,同时让附加功能能够集中在一起也有利于统一维护。
代理场景:
- 代理:将非核心逻辑剥离出来以后,封装这些非核心逻辑的类、对象、方法。(中介)
- 动词:指做代理这个动作,或这项工作
- 名词:扮演代理这个角色的类、对象、方法
- 目标:被代理“套用”了非核心逻辑代码的类、对象、方法。代理在开发中实现的方式具体有两种:静态代理,动态代理。
② 静态代理
主动创建代理类:
public class CalculatorStaticProxy implements Calculator { // 将被代理的目标对象声明为成员变量private Calculator target; public CalculatorStaticProxy(Calculator target) {this.target = target;} @Overridepublic int add(int i, int j) { // 附加功能由代理类中的代理方法来实现System.out.println("参数是:" + i + "," + j); // 通过目标对象来实现核心业务逻辑int addResult = target.add(i, j); System.out.println("方法内部 result = " + result); return addResult;}……
静态代理确实实现了解耦,但是由于代码都写死了,完全不具备任何的灵活性。就拿日志功能来说,将其他地方也需要附加日志,那还得再声明更多个静态代理类,那就生产了大量重复代码,日志功能还是分散的,没有统一管理。
③ 动态代理
- JDK动态代理:JDK原生的实现方式,需要被代理的目标类必须实现接口!它会根据目标类的接口动态生成一个代理对象!代理对象和目标对象有相同的接口!(拜把子)
- cglib:通过继承被代理的目标类实现代理,所以不需要目标类实现接口!(认干爹)
代理工程:基于jdk代理技术,生成代理对象
public class ProxyFactory<T> {//目标对象。具体什么类型由调用者指定private T target;public ProxyFactory(T target) {this.target = target;}public T getProxy(){//1、获取目标对象的类加载器ClassLoader classLoader = target.getClass().getClassLoader();//2、获取目标对象所实现的所有对象Class<?>[] interfaces = target.getClass().getInterfaces();//1、JDK动态代理方式:T o = (T)Proxy.newProxyInstance(classLoader, interfaces, new MyInvocationHandler());return o;}public class MyInvocationHandler implements InvocationHandler{@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//反射角度:method是目标方法,args是目标方法执行时所需要的参数。System.out.println("日志功能,"+method.getName()+"方法执行了,参数为:"+ Arrays.toString(args));//核心:目标方法Object result = method.invoke(target, args);System.out.println("日志功能,"+method.getName()+"方法执行结束,结果为:"+ result);return result;}}
}
④ 代理总结
代理方式可以解决附加功能代码干扰核心代码和不方便统一维护的问题!
它主要是将附加功能代码提取到代理中执行,不干扰目标核心代码。但是我们也发现,无论使用静态代理和动态代理,程序员的工作都比较繁琐,需要自己编写代理工厂等。但是,提前剧透,我们在实际开发中,不需要编写代理代码,我们可以使用SpringAOP框架,它会简化代理的实现!
3、面向切面编程思维(AOP)
1)面向切面编程思想AOP
AOP:Aspect Oriented Programming 面向切面编程
AOP可以说是OOP的补充和完善。OOP引入封装、继承、多态等概念来建立一种对象层次结构,用于模拟公共行为的一个集合。不过OOP允许开发者定义纵向的关系,但并不适合定义横向的关系,例如日志功能。日志代码往往横向地散布在所有对象层次中,而与它对应的对象的核心功能毫无关系对于其他类型的代码,如安全性、异常处理和透明的持续性也都如此,这种散布在各处的无关的代码被称为横切,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。
相关文章:

Spring企业开发核心框架-下
五、Spring AOP面向切面编程 1、场景设定和问题复现 ①准备AOP项目 项目名:Spring-aop-annotation ②声明接口 /*** - * / 运算的标准接口!*/ public interface Calculator { int add(int i, int j); int sub(int i, int j); int mul(int i, in…...

X射线底片焊缝缺陷检测
实现四种焊缝缺陷的检测和分割处理。...

直播的js代码debug解析找到protobuf消息的定义
我们都知道直播的弹幕消息是通过websocket发送的,而且是通过protobuf传输的,那么这里面传输了哪些内容,这个proto文件又要怎么定义?每个消息叫什么,消息里面又包含有哪些字段,每个字段又是什么类型…...
详细学习es6扩展运算符
ES6中的扩展运算符(Spread Operator)是一种非常方便的语法,主要用于将可迭代对象(比如数组、字符串等)展开成多个参数。以下是关于ES6扩展运算符的详细内容: 用法: 在数组字面量中展开数组&am…...

HEC-HMS水文模型教程
原文链接:HEC-HMS水文模型教程https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247607904&idx5&sn1a210328a3fc8f941b433674d8fe2c85&chksmfa826787cdf5ee91d01b6981ebd89deac3e350d747d0fec45ce2ef75d7cb8009341c6f55114d&token90645021…...

Spring Cloud LoadBalancer基础入门与应用实践
官网地址:https://docs.spring.io/spring-cloud-commons/reference/spring-cloud-commons/loadbalancer.html 【1】概述 Spring Cloud LoadBalancer是由SpringCloud官方提供的一个开源的、简单易用的客户端负载均衡器,它包含在SpringCloud-commons中用…...

layui在表格中嵌入上传按钮,并修改上传进度条
当需要在表格中添加上传文件按钮,并不需要弹出填写表单的框的时候,需要在layui中,用按钮触发文件选择 有一点需要说明的是,layui定义table并不是在定义的标签中渲染,而是在紧接着的标签中渲染,所以要获取实…...

14-10 AIGC 项目生命周期——第一阶段
生成式 AI 项目生命周期的整个过程类似于从范围、选择、调整和对齐/协调模型以及应用程序集成开始的顺序依赖过程。流程表明每个步骤都建立在前一步的基础上。有必要了解每个阶段对于项目的成功都至关重要。 下面的流程图重点介绍了生成式 AI 项目生命周期的第一阶段 1 — “范…...

经典小游戏(一)C实现——三子棋
switch(input){case 1:printf("三子棋\n");//这里先测试是否会执行成功break;case 0:printf("退出游戏\n");break;default :printf("选择错误,请重新选择!\n");break;}}while(input);//直到输入的结果为假,循环才会结束} …...

如何利用AI生成可视化图表(统计图、流程图、思维导图……)免代码一键绘制图表
由于目前的AI生成图表工具存在以下几个方面的问题: 大多AI图表平台是纯英文,对国内用户来说不够友好;部分平台在生成图表前仍需选择图表类型、配置项,操作繁琐;他们仍需一份规整的数据表格,需要人为对数据…...

Firefox 编译指南2024 Windows10-使用Git 管理您的Firefox(五)
1. 引言 在现代软件开发中,版本控制系统(VCS)是不可或缺的工具,它不仅帮助开发者有效管理代码的变化,还支持团队协作与项目管理。Mercurial 是一个高效且易用的分布式版本控制系统,其设计目标是简洁、快速…...

ubuntu 18 虚拟机安装(1)
ubuntu 18 虚拟机安装 ubuntu 18.04.6 Ubuntu 18.04.6 LTS (Bionic Beaver) https://releases.ubuntu.com/bionic/ 参考: 设置固定IP地址 https://blog.csdn.net/wowocpp/article/details/126160428 https://www.jianshu.com/p/1d133c0dec9d ubuntu-18.04.6-l…...

Github 上 Star 数最多的大模型应用基础服务 Dify 深度解读(一)
背景介绍 接触过大模型应用开发的研发同学应该都或多或少地听过 Dify 这个大模型应用基础服务,这个项目自从 2023 年上线以来,截止目前(2024-6)已经获得了 35k 多的 star,是目前大模型应用基础服务中最热门的项目之一…...
XStream导出xml文件
最终效果 pom依赖 <dependency><groupId>com.thoughtworks.xstream</groupId><artifactId>xstream</artifactId><version>1.4.11.1</version></dependency>代码 XStreamUtil 这个直接复制即可 import com.thoughtworks.xst…...
陪诊小程序搭建:构建便捷医疗陪诊服务的创新实践
在当今快节奏的社会,医疗服务与人们的生活息息相关。然而,在医疗体系中,患者往往面临着信息不对称、流程繁琐、陪伴需求得不到满足等问题。为了解决这些问题,我们提出了一种创新的解决方案——陪诊小程序,旨在为患者提…...
0139__TCP协议
全网最详细TCP参数讲解,再也不用担心没有面试机会了_tcp的参数-CSDN博客 TCP协议详解-腾讯云开发者社区-腾讯云 TCP-各种参数 - 简书...

家政小程序的开发,带动市场快速发展,提高家政服务质量
当下生活水平逐渐提高,也增加了年轻人的工作压力,同时老龄化也在日益增加,使得大众对家政的需求日益提高,能力、服务质量高的家政人员能够有效提高大众的生活幸福指数。 但是,传统的家政服务模式存在着效率低、用户与…...
JavaScript高级程序设计(第四版)--学习记录之对象、类与面向对象编程(下)
类 ES6新引入class关键字具有正式定义类的能力。 类定义:类声明和类表达式。 // 类声明 class Person {} // 类表达式 const Animal class {}; 类定义与函数定义的不同: 1:函数声明可以提升,类定义不能 2:函数受函数…...

PDF 生成(5)— 内容页支持由多页面组成
当学习成为了习惯,知识也就变成了常识。 感谢各位的 关注、点赞、收藏和评论。 新视频和文章会第一时间在微信公众号发送,欢迎关注:李永宁lyn 文章已收录到 github 仓库 liyongning/blog,欢迎 Watch 和 Star。 回顾 在本篇开始…...
day 51 115.不同的子序列 583. 两个字符串的删除操作 72. 编辑距离
115. 不同的子序列 给你两个字符串 s 和 t ,统计并返回在 s 的 子序列 中 t 出现的个数,结果需要对 109 7 取模。 示例 1: 输入:s "rabbbit", t "rabbit" 输出:3 解释: 如下所示,…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

认识CMake并使用CMake构建自己的第一个项目
1.CMake的作用和优势 跨平台支持:CMake支持多种操作系统和编译器,使用同一份构建配置可以在不同的环境中使用 简化配置:通过CMakeLists.txt文件,用户可以定义项目结构、依赖项、编译选项等,无需手动编写复杂的构建脚本…...

FFmpeg avformat_open_input函数分析
函数内部的总体流程如下: avformat_open_input 精简后的代码如下: int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...
【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权
摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题:安全。文章将详细阐述认证(Authentication) 与授权(Authorization的核心概念,对比传统 Session-Cookie 与现代 JWT(JS…...