Spring AOP的应用

目录

1、maven坐标配置与xml头配置

2、代理方式的选择与配置

3、AOP的三种配置方式

3.1、XML模式

3.1.1 创建目标类和方法

3.1.2 创建切面

3.1.3 切面xml配置与表达式说明

3.1.4 单测

3.2 纯注解模式

3.2.1 开启注解相关配置

3.2.2 创建目标类和方法

3.2.3 创建切面并配置切面

3.2.4 单测

3.3 XML+注解模式

3.3.1 与纯注解模式配置的区别

3.3.2 单测


AOP本质:在不改变原有业务逻辑的情况下增强横切逻辑,横切逻辑代码往往是权限校验代码、⽇志代码、事务控制代码、性能监控代码。

AOP的实现,主要靠动态代理技术,在运行期对需要使用的业务逻辑方法进行增强。

1、maven坐标配置与xml头配置

<!-- Spring AOP核心包 --><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>5.1.12.RELEASE</version></dependency><!-- Spring AOP注解配置包 --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.4</version></dependency><!--junit 单元测试依赖 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency>

Spring基于XML的AOP配置前准备

在已经配置了ioc的xml文件上进行添加   bean.xml

<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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd">

2、代理方式的选择与配置

Spring 实现AOP思想使⽤的是动态代理技术。

默认情况下,Spring会根据被代理对象是否实现接⼝来选择使⽤JDK还是CGLIB。

当被代理对象没有实现任何接⼝时,Spring会选择CGLIB。

当被代理对象实现了接⼝,Spring会选择JDK官⽅的代理技术。

⽆论被代理对象是否实现接⼝,只要不是final修饰的类都可以采⽤cglib提供的⽅式创建代理对象。不过我们可以通过配置的⽅式,让Spring强制使⽤CGLIB。配置方式有以下两种

  • 使⽤aop:config标签配置

<aop:config proxy-target-class="true">
  • 使⽤aop:aspectj-autoproxy标签配置

<!--此标签是基于XML和注解组合配置AOP时的必备标签,表示Spring开启注解配置AOP的⽀持--><aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>

3、AOP的三种配置方式

Spring的AOP和IOC一样,支持三类配置方式:

第⼀类:使⽤XML配置

第⼆类:使⽤纯注解配置

第三类:使⽤XML+注解组合配置

3.1、XML模式

3.1.1 创建目标类和方法

public class TargetObject{public void printLog(String content) {System.out.println("printLog打印目标内容:" + content);}}

3.1.2 创建切面

切面是指增强的代码,增强的代码类,就是切面类。比如:事务切面类,里面定义的方法就是事务相关的,像开启事务,提交事务,回滚事务等等。

public class LogUtil {public void beforeLog() {System.out.println("AOP切面前置通知打印");}public void afterLog() {System.out.println("AOP切面后置通知打印");}public void afterReturnLog() {System.out.println("AOP切面返回值通知打印");}public void afterThrowLog() {System.out.println("AOP切面异常通知打印");}public void aroundLog() {System.out.println("AOP切面环绕通知打印");}}

3.1.3 切面xml配置与表达式说明

bean.xml

<!-- 将相关Bean注入IOC容器--><bean id="logUtil" class="com.test.LogUtil"/><bean id="targetObject" class="com.test.TargetObject"/><!-- 声明AOP配置 --><aop:config><!-- 配置切入点表达式 --><aop:pointcut id="cutPrintLog" expression="execution(public * com.test.TargetObject.printLog(java.lang.String))"/><!-- 配置切面 --><aop:aspect id="aoplog" ref="logUtil"><!-- 配置前置通知 --><aop:before method="beforeLog" pointcut-ref="cutPrintLog"/><!-- 配置后置通知 --><aop:after method="afterLog" pointcut-ref="cutPrintLog"/><!-- 配置返回值通知 --><aop:after-returning method="afterReturnLog" pointcut-ref="cutPrintLog"/><!-- 配置异常通知 --><!--<aop:after-throwing method="afterThrowLog" pointcut-ref="cutPrintLog"/>--><!-- 配置前置通知 --><!--<aop:around method="aroundLog" pointcut-ref="cutPrintLog"/>--></aop:aspect></aop:config>

属性说明:

method:⽤于指定通知的⽅法名称

pointcut:⽤于指定切⼊点表达式

pointcut-ref:⽤于指定切⼊点表达式的引⽤

切入点表达式使用示例

全限定⽅法名 访问修饰符 返回值 包名.包名.包名.类名.⽅法名(参数列表)全匹配⽅式:public void com.test.TargetObject.printLog(java.lang.String)访问修饰符可以省略void com.test.TargetObject.printLog(java.lang.String)返回值可以使⽤*,表示任意返回值* com.test.TargetObject.printLog(java.lang.String)包名可以使⽤.表示任意包,但是有⼏级包,必须写⼏个* ....TargetObject.printLog(java.lang.String)包名可以使⽤..表示当前包及其⼦包* ..TargetObject.printLog(java.lang.String)类名和⽅法名,都可以使⽤.表示任意类,任意⽅法* ...(java.lang.String)参数列表,可以使⽤具体类型基本类型直接写类型名称 : int引⽤类型必须写全限定类名:java.lang.String参数列表可以使⽤*,表示任意参数类型,但是必须有参数* *..*.*(*)参数列表可以使⽤..,表示有⽆参数均可。有参数可以是任意类型* *..*.*(..)全通配⽅式:* *..*.*(..)

3.1.4 单测

@Testpublic void test01() {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");TargetObject target = (TargetObject) context.getBean("targetObject");target.printLog("aaa");}

打印结果:

AOP切面前置通知打印printLog打印目标内容:aaaAOP切面后置通知打印AOP切面返回值通知打印

3.2 纯注解模式

3.2.1 开启注解相关配置

@Configuration@ComponentScan("com.test")// 开启注解支持@EnableAspectJAutoProxypublic class LoggingConfig {}

3.2.2 创建目标类和方法

@Component("targetObject")public class TargetObject{public void printLog(String content) {System.out.println("printLog打印目标内容:" + content);}}

3.2.3 创建切面并配置切面

@Component@Aspectpublic class LogUtil {@Pointcut("execution(* com.test.TargetObject.printLog(..))")public void pointcut(){}@Before("pointcut()")public void beforePrintLog(JoinPoint jp){Object[] args = jp.getArgs();System.out.println("前置通知:beforePrintLog,参数是:"+Arrays.toString(args));}@AfterReturning(value = "pointcut()",returning = "rtValue")public void afterReturningPrintLog(Object rtValue){System.out.println("后置通知:afterReturningPrintLog,返回值 是:"+rtValue);}@AfterThrowing(value = "pointcut()",throwing = "e")public void afterThrowingPrintLog(Throwable e){System.out.println("异常通知:afterThrowingPrintLog,异常是:"+e);}@After("pointcut()")public void afterPrintLog(){System.out.println("最终通知:afterPrintLog");}/*** 环绕通知* @param pjp* @return*/@Around("pointcut()")public Object aroundPrintLog(ProceedingJoinPoint pjp){//定义返回值Object rtValue = null;try{//前置通知System.out.println("前置通知");//1.获取参数Object[] args = pjp.getArgs();//2.执⾏切⼊点⽅法rtValue = pjp.proceed(args);//后置通知System.out.println("后置通知");}catch (Throwable t){//异常通知System.out.println("异常通知");t.printStackTrace();}finally {//最终通知System.out.println("最终通知");}return rtValue;}}

3.2.4 单测

@Testpublic void test02() {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(LoggingConfig.class);TargetObject target = (TargetObject) context.getBean("targetObject");target.printLog("aaa");}

打印结果:

前置通知前置通知:beforePrintLog,参数是:[aaa]printLog打印目标内容:aaa后置通知最终通知最终通知:afterPrintLog后置通知:afterReturningPrintLog,返回值 是:null

3.3 XML+注解模式

3.3.1 与纯注解模式配置的区别

将 3.2.1 的LoggingConfig去掉,用xml配置;

将 3.2.2 和 3.2.3 的 @Component 去掉,用xml注入

<!-- XML中开启Spring对注解AOP的⽀持 -->
<aop:aspectj-autoproxy/><bean id="logUtil" class="com.test.LogUtil"/><bean id="targetObject" class="com.test.TargetObject"/>

3.3.2 单测

@Testpublic void test01() {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");TargetObject target = (TargetObject) context.getBean("targetObject");target.printLog("aaa");}

打印结果:

前置通知前置通知:beforePrintLog,参数是:[aaa]printLog打印目标内容:aaa后置通知最终通知最终通知:afterPrintLog后置通知:afterReturningPrintLog,返回值 是:null

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

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

相关文章

FGPA实验——触摸按键

本文系列都基于正点原子新起点开发板 FPGA系列 1&#xff0c;verlog基本语法&#xff08;随时更新&#xff09; 2&#xff0c;流水灯&#xff08;待定&#xff09; 3&#xff0c;FGPA实验——触摸按键 一、触摸操作原理实现 分类&#xff1a;电阻式&#xff08;不耐用&…

二叉树进阶

目录 1. 二叉搜索树实现 1.1 二叉搜索树概念 2.2 二叉搜索树操作 ​编辑 ​编辑 2.3 二叉搜索树的实现 2.3.0 Destroy() 析构 2.3.1 Insert&#xff08;&#xff09;插入 2.3.2 InOrder&#xff08;&#xff09; 打印搜索二叉树 ​编辑​编辑 2.3.3 Find() 查找 …

el-table表格点击该行任意位置时也勾选上其前面的复选框

需求&#xff1a;当双击表格某一行任意位置时&#xff0c;自动勾选上其前面的复选框 1、在el-table 组件的每一行添加row-dblclick事件&#xff0c;用于双击点击 <el-table:data"tableData"ref"tableRef"selection-change"handleSelectionChange&q…

几种主流的`Content-Type`与其对应的数据格式的例子

application/json: 用于发送和接收JSON格式的数据。例如&#xff0c;可以使用以下代码将JSON数据发送到服务器&#xff1a; $.ajax({url: "/api/endpoint",type: "POST",contentType: "application/json",data: JSON.stringify({ key: "va…

如何在Chrome最新浏览器中调用ActiveX控件?

小编最近登陆工商银行网上银行&#xff0c;发现工商银行的个人网银网页&#xff0c;由于使用了ActiveX安全控件&#xff0c;导致不能用高版本Chrome浏览器打开&#xff0c;目前只有使用IE或基于IE内核的浏览器才能正常登录网上银行&#xff0c;而IE已经彻底停止更新了&#xff…

AI绘图网页版工具

https://chat.bushao.info/?inVitecodeCHBEPQQOOM 一款AI绘图工具&#xff0c;很好玩&#xff0c;推荐&#xff1b; 我自己根据文本生成的图&#xff0c;感觉还不错。

深入理解Java中的序列化与反序列化

目录 1. 引言 2. 什么是序列化&#xff1f; 3. 为什么需要序列化&#xff1f; 4. 如何实现序列化&#xff1f; 5. 示例代码 6. 序列化和反序列化操作 7. 注意事项 8. 拓展&#xff1a;Transient关键字 9. 拓展&#xff1a;序列化的性能优化 10. 结论 1. 引言 在软件…

ROC、TPR、FPR的含义

1、ROC&#xff08;Receiver Operating Characteristic&#xff09; ROC&#xff08;Receiver Operating Characteristic&#xff09;曲线是一种用于评估分类模型性能的工具。它通过绘制真阳性率&#xff08;True Positive Rate, TPR&#xff09;与假阳性率&#xff08;False…

仪表放大器AD620

AD623 是一款低功耗、高精度的仪表放大器&#xff0c;而不是轨到轨运算放大器。它的输入电压范围并不覆盖整个电源电压&#xff08;轨到轨&#xff09;&#xff0c;但在单电源供电下可以处理接近地电位的输入信号。 AD620 和 AD623 都是仪表放大器&#xff0c;但它们在一些关键…

vscode【实用插件】Notes 便捷做笔记

安装 在 vscode 插件市场的搜索 Notes点 安装 安装成功后&#xff0c;vscode 左侧栏会出现 使用 初次使用 需先选择一个本地目录 重启 vscode 后&#xff0c;得到 切换笔记目录 新建笔记 快捷键为 Alt N 默认会创建 .md 文件 配合插件 Markdown Preview Enhanced 预览 .md…

Go语言中的Mutex实现探讨

解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在并发编程中,互斥锁(Mutex)是一个重要的工具,它帮助我们控制多个协程对共享资源的访问,从而防止数据竞争和不一致性。本文将深入探讨Go语言中Mutex的实现历程和使用方式,同时分享在处理并发问题时的思路与…

Spring Service中的@Service注解的使用

Service注解是Spring框架中用于标识业务逻辑层&#xff08;Service层&#xff09;的注解。它是Spring组件扫描机制的一部分&#xff0c;表明这个类包含业务逻辑&#xff0c;并且应该由Spring容器管理为一个Spring Bean。它与Component类似&#xff0c;都是标识一个类为Spring管…

RestCloud webservice 流程设计

RestCloud webservice 流程设计 操作步骤 离线数据集成&#xff08;首页&#xff09; → \rightarrow → 示例应用数据集成流程&#xff08;边栏&#xff09; → \rightarrow → 所有数据流程 → \rightarrow → webservice节点获取城市列表 → \rightarrow → 流程设计 …

Linux网络——HTTPS详解

文章目录 HTTPS加密 常见加密方式对称加密非对称加密非对称对称数据指纹 证书CA认证数字签名非对称证书对称 中间人 HTTPS 这也是一个应用层协议&#xff0c;是在HTTP协议的基础上引入了一个加密层 为什么要加密呢&#xff0c;这主要是因为如果不对传输主体加密&#xff0c;当…

鹏哥C语言53---第8次作业:函数传参

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <math.h> //--------------------------------------------------------------------------------------------- 第 8 次作业 函数传参等 //-----------------------------------------------------…

2024中国新能源汽车零部件交易会,开源网安展示了什么?

近日&#xff0c;2024中国新能源汽车零部件交易会在十堰国际会展中心举行。开源网安车联网安全实验室携车联网安全相关产品及解决方案亮相本次交易会&#xff0c;保障智能网联汽车“车、路、云、网、图、边”安全&#xff0c;推动智能网联汽车技术突破与产业化发展。 中国新能源…

【深度学习】(7)--神经网络之保存最优模型

文章目录 保存最优模型一、两种保存方法1. 保存模型参数2. 保存完整模型 二、迭代模型 总结 保存最优模型 我们在迭代模型训练时&#xff0c;随着次数初始的增多&#xff0c;模型的准确率会逐渐的上升&#xff0c;但是同时也随着迭代次数越来越多&#xff0c;由于模型会开始学…

【从0开始自动驾驶】用python做一个简单的自动驾驶仿真可视化界面

【从0开始自动驾驶】用python做一个简单的自动驾驶仿真可视化界面 废话几句废话不多说&#xff0c;直接上源码目录结构init.pysimulator.pysimple_simulator_app.pyvehicle_config.json 废话几句 自动驾驶开发离不开仿真软件成品仿真软件种类多https://zhuanlan.zhihu.com/p/3…

【CSS】鼠标 、轮廓线 、 滤镜 、 堆叠层级

cursor 鼠标outline 轮廓线filter 滤镜z-index 堆叠层级 cursor 鼠标 值说明值说明crosshair十字准线s-resize向下改变大小pointer \ hand手形e-resize向右改变大小wait表或沙漏w-resize向左改变大小help问号或气球ne-resize向上右改变大小no-drop无法释放nw-resize向上左改变…

蓝桥杯1.小蓝的漆房

样例输入 2 5 2 1 1 2 2 1 6 2 1 2 2 3 3 3样例输出 1 2 import math import os import sys tint(input())#执行的次数 for j in range(t):n,kmap(int,input().split())#n为房间数 k为一次能涂的个数alist(map(int,input().split()))#以列表的形式存放房间的颜色maxvaluemath…