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君将会第一时间发布选题建议、所有题目的思路解析、相关代码、参考文献、参考论文等多项资料&…

关于跨域引用界面cookie不支持的处理

缘由&#xff1a;项目上与其他公司做对接&#xff0c;对方使用iframe引用我方项目&#xff0c;不使用nginx做代理&#xff0c;设置了老三样跨域请求头&#xff08;Access-Control-Allow&#xff09;&#xff0c;发现跨域cookie不识别&#xff0c;每次请求时返回头都携带新cooki…

docker filebeat 将日志多级目录和多维json数据日志同步到es

注 使用的时候先调试调试配置,调试成功在尝试写入es,如果es写入失败就是es账户.密码/白名单.和index未创建的问题,细节可以留言 setup.template.priority 模板优先级 调整这个可以配置一台机器多个filebeat 容器启动 多级目录日志和多维josn日志结构 filebeat.inputs:- typ…

如何使用ThinkPHP框架(thinkphp8.0)创建定时任务?

1、安装定时任务composer包 composer require easy-task/easy-task 2、创建命令行处理类文件 php think make:command Task task 会生成文件&#xff1a;app\command\Task.php 将Task.php文件内容修改如下&#xff1a; <?php declare (strict_types1);namespace app…

Jira REST API_检索多选自定义字段的可用选项

文章目录 背景解决方案背景 Jira Server/Data Center REST API不提供简单检索多选项自定义字段可用的所有选项的方法,只有 rest/api/2/customFieldOption/{id} API 获取指定的id的option值。 本文提供一种解决方法,,用于在通过 REST API 创建或编辑问题之前检索所有自定义字…

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;各自以独特的优势展现在用户面前。本文将…

【cuda】Visual Studio中进行CUDA程序的性能评估

在Visual Studio中使用Nsight进行CUDA应用程序的性能评估可以按照以下步骤进行&#xff1a; 步骤 1: 准备工作 确保已经安装了以下组件&#xff1a; 最新版本的NVIDIA驱动。NVIDIA Nsight Visual Studio Edition&#xff08;通常与CUDA Toolkit一起安装&#xff09;。Micros…

history 模式刷新 404 问题解决方法

在使用 Vue Router 的 history 模式时&#xff0c;刷新页面可能会导致出现 404 错误。这是因为 history 模式依赖于浏览器的 history.pushState API 来管理路由状态&#xff0c;而刷新页面时浏览器会向服务器发送请求&#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/…

vue之虚拟滚动

一、解决的问题 对于大量数据的懒加载&#xff0c;我们可以使用虚拟滚动的技术。虚拟滚动的原理是只渲染可视区域内的数据&#xff0c;当用户滚动时&#xff0c;动态计算并渲染新的可视数据&#xff0c;从而实现大数据量的流畅滚动。 在Vue中&#xff0c;我们可以使用第三方库…