Spring基于AOP(面向切面编程)开发

概述

        AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

为什么要学习AOP

在不修改源代码的情况下,对原方法进行增强

AOP可以校验,日志记录,性能监控,事务控制

底层实现(了解)

代理机制:

Spring的AOP的底层用到两种代理机制

        JDK动态代理:针对实现了接口的类产生的代理

        Cglib动态代理:针对没有接口的类产生的代理,应用了底层的字节码增强的技术,生成当前的子类对象

JDK动态代理

创建一个代理类

public class ProxyUser implements InvocationHandler {private Object target; // 代理的目标对象public LogJdkProxy(Object target) {this.target = target;}/** 创建代理对象 */public Object createProxyInstance() {// 第1个参数设置代码使用的类装载器,一般采用跟目标类相同的类装载器// 第2个参数设置代理类实现的接口// 第3个参数设置回调对象,当代理对象的方法被调用时,会调用该参数指定对象的invoke方法return Proxy.newProxyInstance(//getClass().getClassLoader(), // 第1个参数target.getClass().getInterfaces(), // 第2个参数this); // 第3个参数}/*** @param proxy  目标对象的代理类实例* @param method 对应于在代理实例上调用接口方法的Method实例* @param args   传入到代理实例上方法参数值的对象数组* @return 方法的返回值,没有返回值(void)时是null*/public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("== Log:开始执行操作,方法名:"+method.getName()+" ==");Object result = method.invoke(target, args); // 执行原方法,把方法调用委派给目标对象System.out.println("== Log:操作执行完毕 ==");return result;}
}

测试

Cglib动态代理

创建对象接口

// 此类不能是final的,否则不能有子类,CGLIB也就不能工作了
public class UserServiceImpl {// 这是final的方法,不能被子类重写,所以CGLIB不会拦截这个方法public final void foo1() {System.out.println(">> final的方法 <<");}// 这是static的方法,CGLIB不会拦截这个方法public static void foo2() {System.out.println(">> static的方法 <<");}// 这是private的方法,CGLIB不会拦截这个方法private void foo3() {System.out.println(">> private的方法 <<");}// CGLIB会拦截这个方法,可以是public, protected, default的修饰符public void deleteUser() {System.out.println(">> 删除一个User <<");}
}

创建Cglib代理类

// CGLIB代理类
public class LogCglibProxy implements MethodInterceptor {private Object target; // 代理的目标对象/*** 创建代理对象* @param <T>* @param target 目标对象*/public <T> T createProxyInstance(T target) {this.target = target;Enhancer enhancer = new Enhancer(); // 该类用于生成代理对象enhancer.setSuperclass(target.getClass()); // 设置父类enhancer.setCallback(this); // 设置回调对象为自己这个对象return (T) enhancer.create(); // 创建代理对象并返回}/*** @param proxy 		 目标对象代理类的实例* @param method		代理类实例上调用父类方法的Method实例* @param args 			传入到方法参数值的对象数组* @param methodProxy 	使用它调用父类的方法*/@Overridepublic Object intercept(Object proxy, Method method, Object[] args, 
MethodProxy methodProxy)	throws Throwable {System.out.println(proxy.getClass());System.out.println("== Log:开始执行操作,方法名:" + method.getName() + " ==");Object result = methodProxy.invoke(target, args); // 执行原方法System.out.println("== Log:操作执行完毕 ==");return result;}
}

测试

public class MainTest {@Testpublic void test() throws Exception {UserService userService = new UserService();userService = (UserService) new LogCglibProxy().createProxyInstance(userService); // 使用包装之的后的代理对象userService.saveUser();System.out.println();userService.deleteUser();System.out.println();
}
}

Spring使用AspectJ进行AOP开发

引入lib包

引入配置文件

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>
使用xml配置文件形式

通知类型

切入点表达式

编写一个切面类

public class MyAspectXml {
// 前置增强
public void before(){
System.out.println("前置增强===========");}
}

在application Context.xml中配置

<!-- 配置切面类 -->
<bean id="myAspectXml" class="cn.test.spring.demo3.MyAspectXml"></bean>
<!-- 进行 aop 的配置 -->
<aop:config>
<!-- 配置切入点表达式:哪些类的哪些方法需要进行增强 -->
<aop:pointcut expression="execution(* cn.test.spring.demo3.OrderDao.save(..))" id="pointcut1"/>
<!-- 配置切面 -->
<aop:aspect ref="myAspectXml">
<aop:before method="before" pointcut-ref="pointcut1"/> </aop:aspect>
</aop:config>
使用注解来实现切面类

开启aop注解自动代理

AspectJ的AOP注解

@Aspect  定义切面类

通知类型

@Before        前置通知

@AfterReturing        后置通知

@Around        环绕通知

@After        最终通知

@AfterThrowing        异常抛出通知

@Pointcut        定义切入点

编写切面类

@Component
@Aspect
public class MyAspect {@Before("MyAspect.pointcut01()")public void before(){System.out.println("前置-----");}@After("MyAspect.pointcut01()")public void after(){System.out.println("后置-----");}@Pointcut("execution(* com.xuexi.dao.*.*(..))")public void pointcut01(){}
}

测试

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

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

相关文章

鸿蒙开发之手势Pan

Entry Component struct OfficialPanGesturePage {State message: string 默认只左右移动State offsetX: number 0State offsetY: number 0State positionX: number 0State positionY: number 0//默认pan的参数&#xff0c;1根手指&#xff0c;左右方向private panOption:…

Audio Precision SYS-2722音频分析仪

181/2461/8938产品概述&#xff1a; 2700系列专为需要最高性能的音频工程师而设计&#xff0c; 最低的失真和最大的灵活性。 2722的真正双域架构实现了以下方面的无与伦比的测量 模拟和数字信号:模拟发生器和分析仪性能超过 任何基于数字转换器的设计&#xff0c;而数字分析技…

三、基础篇 vue Class与Style绑定

操作元素的 class 列表和内联样式是数据绑定的一个常见需求。因为它们都是 attribute&#xff0c;所以我们可以用 v-bind 处理它们&#xff1a;只需要通过表达式计算出字符串结果即可。不过&#xff0c;字符串拼接麻烦且易错。因此&#xff0c;在将 v-bind 用于 class 和 style…

【面试突击】计算级网络面试实战(上)

&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308; 欢迎关注公众号&#xff08;通过文章导读关注&#xff1a;【11来了】&#xff09;&#xff0c;及时收到 AI 前沿项目工具及新技术 的推送 发送 资料 可领取 深入理…

2024年美赛美国大学生数学建模竞赛ABCDEF题思路资料汇总贴

下文包含&#xff1a;2024年美国大学生数学建模竞赛&#xff08;美赛&#xff09;A- F题思路解析、选题建议、代码可视化及如何准备数学建模竞赛&#xff08;2号发&#xff09; C君将会第一时间发布选题建议、所有题目的思路解析、相关代码、参考文献、参考论文等多项资料&…

Linux:为什么要打包和压缩?

我们在Linux中已经学习了zip/unzip和tar两种方式来打包压缩文件&#xff0c;那么为什么要打包和压缩呢&#xff1f; 最直接的目的就是为了便于网络传输&#xff0c;防止传输过程中的数据丢失 举例实践 我们做个示例演示一下 我们创建一百个文件 我们将文件都放到dir里面来&…

UDP传输总丢包?常用的解决方式在这里!

UDP是一种无连接的协议&#xff0c;传输数据时不建立连接&#xff0c;因此可能导致数据包丢失。UDP丢包是指在传输过程中由于各种原因导致数据包未能到达目的地。UDP丢包会影响传输的质量和效率&#xff0c;导致数据损失、延迟&#xff0c;甚至导致传输失败。本文将分析UDP丢包…

上门按摩APP系统公众号H5搭建能为客户带来哪些便捷。

大家好&#xff01;今天我来给大家介绍一下上门按摩系统H5搭建。你有没有曾经因为工作疲劳、肌肉酸痛而感到身体不适&#xff1f;或者是因为长时间坐在电脑前&#xff0c;感觉脖子和肩膀快要僵硬了&#xff1f;如果你有这样的困扰&#xff0c;那么上门按摩系统公众号绝对是你的…

高光谱分类论文解读分享之基于多模态融合Transformer的遥感图像分类方法

IEEE TGRS 2023&#xff1a;基于多模态融合Transformer的遥感图像分类方法 题目 Multimodal Fusion Transformer for Remote Sensing Image Classification 作者 Swalpa Kumar Roy , Student Member, IEEE, Ankur Deria , Danfeng Hong , Senior Member, IEEE, Behnood Ras…

Hive 数据迁移

一、需求 同步集团的数据到断直连环境。 二、思路 三、同步数据&#xff08;方案&#xff09; 1、环境&#xff1a;断直连模拟环境 2、操作机器&#xff1a;ETL 机器 XX.14.36.216 3、工作路径&#xff1a;cd /usr/local/fqlhadoop/hadoop/bin 4、执行命令&#xff1a; 命令…

文心一言 vs. ChatGPT:哪个更胜一筹?

文心一言 vs. ChatGPT&#xff1a;从简洁美到深度思考的文本生成之旅 近年来&#xff0c;文本生成工具的崛起使得人们在表达和沟通方面拥有了更多的选择。在这个领域中&#xff0c;文心一言和ChatGPT作为两个备受瞩目的工具&#xff0c;各自以独特的优势展现在用户面前。本文将…

网络设备自动巡检脚本

简介 工作中经常需要对客户的网络设备进行巡检&#xff0c;之前都是用SecureCRT开启记录Log Session&#xff0c;依次远程登录到每个设备上&#xff0c;依次输入巡检命令收集设备巡检信息&#xff1b; 现在希望利用Python能够实现自动登录设备&#xff0c;自动抓取巡检信息&am…

使用新版IDEA社区版创建一个springboot项目(完整详细版)

目录 一、添加依赖二、下载JDK三、配置Maven阿里云镜像Idea中的maven配置当前项目新项目&#xff08;即默认的配置&#xff09; 四、创建项目四、测试项目错误1错误2错误3完整的pom.xml测试结果 IDEA各版本下载链接&#xff1a;https://www.jetbrains.com/zh-cn/idea/download/…

【Dynamo学习笔记】基础入门

目录 前言1 Dynamo的界面2 节点的操作3 几何形体的创建与编辑3.1 几何形体的创建3.1.1 直线3.1.2 圆形3.1.3 多边形3.1.4 长方体3.1.5 球体 3.2 几何形体的编辑3.2.1 坐标点的平移复制3.2.2 几何形体的平移复制3.2.3 几何形体的镜像复制3.2.4 几何形体的旋转复制3.2.5 几何形体…

全方位提升用户数字化体验的解决方案

前言 在数字化的世界中&#xff0c;用户体验越来越成为企业关注的焦点&#xff0c;然而&#xff0c;用户体验极具主观性&#xff0c;科学地评估用户体验&#xff0c;建立科学的量化体系是难上加难。今天介绍全方位提升用户数字化体验的解决方案&#xff0c;方案通过全面观测用…

统计学R语言实验2 :概率与分布

实验2 概率与分布 一、实验目的 1. 掌握理解离散型概率分布的相关概念。 2. 掌握理解连续型概率分布的相关概念。 3. 熟悉R语言等语言的集成开发环境。 二、实验分析与内容 完成教材P52-53的第2题和第8题 &#xfeff; &#xfeff;2.一条食品生产线每8小时一班中出现…

代码随想录算法训练营第29天 |* 491.递增子序列* 46.全排列* 47.全排列 II

目录 * 491.递增子序列 &#x1f4a1;解题思路 回溯三部曲 &#x1f4bb;实现代码 * 46.全排列 &#x1f4a1;解题思路 # 回溯三部曲 单层搜索的逻辑 &#x1f4bb;实现代码 * 47.全排列 II &#x1f4a1;解题思路 &#x1f4bb;实现代码 * 491.递增子序列 题目链…

Qt 国产嵌入式操作系统实现文字转语音功能(TTS)

1.简介 本示例使用的CPU&#xff1a;rk3588。 操作系统&#xff1a;kylin V10 架构&#xff1a;aarch64 在Windows端&#xff0c;我们很容易想到使用Qt自带的类QTextToSpeech来实现文字转语音功能&#xff0c;Qt版本得在5.11.0以上才支持。但是在嵌入式平台&#xff0c;尤其…

表的增删改查CURD(一)

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f525;个人专栏&#xff1a;MySql&#x1f4d5;格言&#xff1a;那些在暗处执拗生长的花&#xff0c;终有一日会馥郁传香欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 新增&#xff08;Create&#xff09; 全列插入 指定列…

【数据结构】二叉树-堆(函数实现)

&#x1f308;个人主页&#xff1a;秦jh__https://blog.csdn.net/qinjh_?spm1010.2135.3001.5343&#x1f525; 系列专栏&#xff1a;《数据结构》https://blog.csdn.net/qinjh_/category_12536791.html?spm1001.2014.3001.5482 ​​ 目录 头文件 函数实现 初始化 销毁 …