spring4第7-8课-AOP的5种通知类型+切点定义详解+执行顺序

继续学习,方便自己复查记录

①AOP简介:
   面向切面编程(也叫面向方面编程):Aspect Oriented Programming(AOP)。
   Spring框架中的一个重要内容。。
   通过预编译方式和运行期间动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。AOP是OOP(面向对象编程)的延续。
   作用: 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高  程序的可重用性,同时提高了开发的效率。
   使用场景:日志记录,性能统计,安全控制,事务处理,异常处理等。

②AOP实例学习:几种通知类型↓↓↓↓

1,前置通知;
2,后置通知;
3,环绕通知;
4,返回通知;
5,异常通知;

②-1首先看下不用AOP前的代码写法,

(作为测试,业务目的很简单:在程序的开始和结束打印一点日志)

代码如下:涉及4个文件

代码1:配置类 bean.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="studentService" class="com.java1234.service.impl.StudentServiceImpl"></bean></beans>代码2:StudentService类
package com.java1234.service;public interface StudentService {public void addStudent(String name);
}代码3:StudentService实现类
package com.java1234.service.impl;import com.java1234.service.StudentService;public class StudentServiceImpl implements StudentService{@Overridepublic void addStudent(String name) {System.out.println("开始添加学生"+name);System.out.println("添加学生"+name);System.out.println("完成学生"+name+"的添加");}}代码4:测试类
package com.java1234.test;import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import com.java1234.service.StudentService;public class T {private ApplicationContext ac;@Beforepublic void setUp() throws Exception {ac=new ClassPathXmlApplicationContext("beans.xml");}@Testpublic void test1() {// 多态特性:父类的引用可以指向具体的实现。// 按照bean.xml的定义,本来 ac.getBean("studentService") 得到的是StudentServiceImpl,被安全的向下转型为StudentService类型StudentService studentService=(StudentService)ac.getBean("studentService");//studentService.addStudent("张三");}}

②-2使用AOP类的变化:

a.增加切面通知类

b.引入相关jar包:aopalliance.jar,aspectjweaver-1.6.6.jar,spring-aspects-4.0.6.RELEASE.jar(版本号可能有差异)

c.在bean.xml中增加

xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation  后面增加http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd

加完上面这个就可以在bean.xml中使用aop功能了  

插入知识点1:bean.xml的命名空间的含义。可以跳过

xsi:schemaLocation 的通用结构为:  命名空间URI1 XSD路径1 命名空间URI2 XSD路径2 ...

例子:(都是两个两个一起的)

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
    
在给定的 xsi:schemaLocation 属性中,每一对字符串分别由命名空间 URI 和 实际 XSD 文件路径组成。具体解析如下:

命名空间 URI
http://www.springframework.org/schema/beans
这是 Spring 框架中 beans 模块的命名空间 URI,用于标识 XML 中相关元素的所属规范。
http://www.springframework.org/schema/aop
这是 Spring AOP 模块的命名空间 URI,用于标识 AOP 相关配置的命名空间。
实际 XSD 文件路径
http://www.springframework.org/schema/beans/spring-beans.xsd
这是 beans 模块对应的 XML Schema 定义文件(XSD)的实际网络路径。
http://www.springframework.org/schema/aop/spring-aop.xsd
这是 AOP 模块对应的 XSD 文件路径,定义了 AOP 配置的校验规则。

插入知识点2:执行表达式execution的理解,可以跳过

执行表达式 execution(* com.java1234.service.*.*(..)) 的含义

该表达式是 Spring AOP 中的切点(Pointcut)表达式,用于匹配特定方法的执行。以下是逐部分解析:

组成部分解析
  1. execution
    表示匹配方法执行的连接点(Join Point),是 AOP 中最常用的切点指示符。

  2. *(第一个星号)
    匹配任意返回类型(如 voidStringint 等)。

  3. com.java1234.service.*
    指定包路径和类名:

    • com.java1234.service 是目标包名。
    • .* 匹配该包下的任意类(但不包括子包中的类)。
  4. *(第三个星号)
    匹配类中的任意方法名。

  5. (..)
    匹配任意参数列表(无论是否有参数,或参数类型是什么)。

完整含义

该表达式匹配:
com.java1234.service 包下任意类中,所有返回类型、所有方法名、所有参数列表的方法。

常见用法示例
@Aspect
@Component
public class ServiceAspect {@Before("execution(* com.java1234.service.*.*(..))")public void logBeforeServiceMethod(JoinPoint joinPoint) {System.out.println("Executing: " + joinPoint.getSignature());}
}

扩展说明
  • 需匹配子包中的类,可使用 ..:(2个点)
    execution(* com.java1234.service..*.*(..))
  • 若需限定方法名,可替换 * 为具体名称(如 get* 匹配以 get 开头的方法)。
相关语法对比
// 匹配特定返回类型(String)的方法
execution(String com.java1234.service.*.*(..))// 匹配特定类(UserService)中的方法
execution(* com.java1234.service.UserService.*(..))// 匹配特定参数类型(需一个Long参数)的方法
execution(* com.java1234.service.*.*(Long))

d.在bean.xml中增加aop切面的定义  ,完整的bean.xml如下↓↓↓↓

<?xml version="1.0" encoding="UTF-8"?>
<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/aophttp://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 引入第三行 xmlns:aop="http://www.springframework.org/schema/aop" 和引入第7.8行 http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd就可以使用AOP功能配置了 --><!-- 切面类是studentServiceAspect(这里有想添加的方法功能) --><bean id="studentServiceAspect" class="com.java1234.advice.StudentServiceAspect"></bean><bean id="studentService" class="com.java1234.service.impl.StudentServiceImpl"></bean><aop:config><!--aop:aspect 配置切面,关联的切面类是studentServiceAspect(这里有想添加的方法功能) --><aop:aspect id="studentServiceAspectConfig" ref="studentServiceAspect"><!-- aop:pointcut 定义1个切点,spring的切点是定义到方法级的。execution是表达式,用于匹配特定方法的执行--><!-- execution(* com.java1234.service.*.*(..)) 用于匹配特定方法的执行   --><aop:pointcut expression="execution(* com.java1234.service.*.*(..))" id="businessService"/><!-- 开始定义各种通知 aop:before  aop:after  aop:around aop:after-returning aop:after-returning aop:after-throwing--><!-- 定义1,前置通知;方法执行前触发. pointcut-ref="businessService" 表示引用的切点是businessService--><aop:before method="doBefore" pointcut-ref="businessService" /><!-- 定义2,后置通知;方法执行后触发(无论是否抛出异常)。 --><!--aop:after method="doAfter" pointcut-ref="businessService"/--><!-- 定义3,环绕通知;包围目标方法,需手动调用 proceed()。 --><aop:around method="doAround" pointcut-ref="businessService" /><!-- 定义4,返回通知; 方法正常返回后触发。--><aop:after-returning method="doAfterReturning" pointcut-ref="businessService"/><!-- 定义5,异常通知   方法抛出异常时触发。--><aop:after-throwing method="doAfterThrowing" pointcut-ref="businessService" throwing="ex"/></aop:aspect></aop:config>
</beans>

其他的代码1,业务类:没有了冗余的日志打印代码,用aop实现了

package com.java1234.service.impl;import com.java1234.service.StudentService;public class StudentServiceImpl implements StudentService{@Overridepublic void addStudent(String name) {// System.out.println("开始添加学生"+name);System.out.println("业务逻辑开始::::添加学生"+name);// System.out.println(1/0);// System.out.println("完成学生"+name+"的添加");}}

 

 代码2: 接口类(匹配上expression="execution(* com.java1234.service.*.*(..))"这里的路径)

package com.java1234.service;public interface StudentService {public void addStudent(String name);
}

 代码3:切面类(5种通知的具体内容)

package com.java1234.advice;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;public class StudentServiceAspect {public void doBefore(JoinPoint jp){System.out.println("doBefore:类名:"+jp.getTarget().getClass().getName());System.out.println("doBefore:方法名:"+jp.getSignature().getName());System.out.println("doBefore:开始添加学生:"+jp.getArgs()[0]);}public void doAfter(JoinPoint jp){System.out.println("doAfter:类名:"+jp.getTarget().getClass().getName());System.out.println("doAfter:方法名:"+jp.getSignature().getName());System.out.println("doAfter:学生添加完成:"+jp.getArgs()[0]);}public Object doAround(ProceedingJoinPoint pjp) throws Throwable{ // 参数和其他通知不一样 ProceedingJoinPointSystem.out.println("doAround:添加学生前");System.out.println("doAround:手动调用 proceed方法");Object retVal=pjp.proceed();  // 需手动调用 proceed()。//System.out.println(retVal);System.out.println("doAround:添加学生后");return retVal;}public void doAfterReturning(JoinPoint jp){System.out.println("doAfterReturning:返回通知");}public void doAfterThrowing(JoinPoint jp,Throwable ex){System.out.println("doAfterThrowing:异常通知");System.out.println("doAfterThrowing:异常信息:"+ex.getMessage());}
}

  代码4:测试类,调用的main类

package com.java1234.test;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import com.java1234.service.StudentService;public class T {public static void main(String[] args) {ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");StudentService studentService=(StudentService)ac.getBean("studentService");studentService.addStudent("张三");}}

 最后:关于5种通知:

1,前置通知;
2,后置通知;
3,环绕通知;
4,返回通知;
5,异常通知;
 

ps1: 第4种返回通知;第5种异常通知; 不会同时存在,只能同时返回1种

ps2. 如果同时存在时的执行顺序:

在业务处理无异常时的执行顺序:

1前置通知--》3环绕通知的前处理--》业务逻辑--》3环绕通知的后处理--》2后置通知--》4返回通知

在业务处理有异常时的执行顺序:

1前置通知--》3环绕通知的前处理--》业务逻辑--》5异常通知

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

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

相关文章

EscapeX:去中心化游戏,开启极限娱乐新体验

VEX 平台推出全新去中心化游戏 EscapeX&#xff08;数字逃脫&#xff09;&#xff0c;创新性地将大逃杀玩法与区块链技术相融合。用户不仅能畅享紧张刺激的解谜过程&#xff0c;更能在去中心化、公正透明的环境中参与游戏。EscapeX 的上线&#xff0c;为 VEX 生态注入全新活力&…

Multi Agents Collaboration OS:Web DeepSearch System

背景&#xff1a;多智能体协作驱动网络信息处理的范式革新 随着大型语言模型&#xff08;LLM&#xff09;能力的突破性进展&#xff0c;人工智能正从“单点赋能”向“系统协同”演进。传统单一智能体在复杂业务场景中逐渐显露局限&#xff1a;面对需多维度知识整合、动态任务拆…

React 第五十三节 Router中 useRouteError 的使用详解和案例分析

前言 useRouteError 是 React Router v6.4 引入的关键错误处理钩子&#xff0c;用于在 路由错误边界&#xff08;Error Boundary&#xff09; 中获取路由操作过程中发生的错误信息。 它提供了优雅的错误处理机制&#xff0c;让开发者能够创建用户友好的错误界面。 一、useRou…

[arthas]arthas安装使用

arthas是阿里开源的一个java线上监控以及诊断工具&#xff0c;在docker容器中我们无需重启服务&#xff0c;也不用更改代码&#xff0c;就可以完成对应用内存、线程、日志级别的修改、方法调用的出入参、异常监测、执行耗时等&#xff0c;xxxx.xxxx.xxxxx为脱敏内容 1. 在docke…

Flask-Babel 使用示例

下面创建一个简单的 Flask-Babel 示例&#xff0c;展示如何在 Flask 应用中实现国际化和本地化功能。这个示例将包括多语言支持&#xff08;中文和英文&#xff09;、语言切换功能以及翻译文本的使用。 项目结构 我们将创建以下文件结构&#xff1a; 1. 首先&#xff0c;创…

[论文阅读] 软件工程 | 量子计算如何赋能软件工程(Quantum-Based Software Engineering)

arXiv:2505.23674 [pdf, html, other] Quantum-Based Software Engineering Jianjun Zhao Subjects: Software Engineering (cs.SE); Quantum Physics (quant-ph) 量子计算如何赋能软件工程 我们在开发软件时&#xff0c;常常会遇到一些棘手的问题。比如&#xff0c;为了确保软…

Ansible 进阶 - Roles 与 Inventory 的高效组织

Ansible 进阶 - Roles 与 Inventory 的高效组织 如果说 Playbook 是一份完整的“菜谱”,那么 Role (角色) 就可以被看作是制作这道菜(或一桌菜)所需的标准化“备料包”或“半成品组件”。例如,我们可以有一个“Nginx Web 服务器安装配置 Role”、“MySQL 数据库基础设置 Ro…

青少年编程与数学 01-011 系统软件简介 04 Linux操作系统

青少年编程与数学 01-011 系统软件简介 04 Linux操作系统 一、Linux 的发展历程&#xff08;一&#xff09;起源&#xff08;二&#xff09;早期发展&#xff08;三&#xff09;成熟与普及&#xff08;四&#xff09;移动与嵌入式领域的拓展 二、Linux 的内核与架构&#xff08…

将图形可视化工具的 Python 脚本打包为 Windows 应用程序

前文我们已经写了一个基于python的tkinter库和matplotlib库的图形可视化工具。 基于Python的tkinter库的图形可视化工具&#xff08;15种图形的完整代码&#xff09;:基于Python的tkinter库的图形可视化工具&#xff08;15种图形的完整代码&#xff09;-CSDN博客 在前文基础上&…

【Kotlin】简介变量类接口

【Kotlin】简介&变量&类&接口 【Kotlin】数字&字符串&数组&集合 【Kotlin】高阶函数&Lambda&内联函数 【Kotlin】表达式&关键字 文章目录 Kotlin_简介&变量&类&接口Kotlin的特性Kotlin优势创建Kotlin项目变量变量保存了指向对…

OpenCV种的cv::Mat与Qt种的QImage类型相互转换

一、首先了解cv::Mat结构体 cv::Mat::step与QImage转换有着较大的关系。 step的几个类别区分: step:矩阵第一行元素的字节数step[0]:矩阵第一行元素的字节数step[1]:矩阵中一个元素的字节数step1(0):矩阵中一行有几个通道数step1(1):一个元素有几个通道数(channel()) cv::Ma…

搭建基于VsCode的ESP32的开发环境教程

一、VsCode搜索ESP-IDF插件 根据插件处搜索找到ESP-IDF并安装 安装完成 二、配置安装ESP-IDF 配置IDF 按照如下配置&#xff0c;点击安装 安装完成 三、使用案例程序 创建一个闪光灯的例子程序&#xff0c;演示程序编译下载。 选择blink例子&#xff0c;闪烁LED的程序 选…

企业培训学习考试系统源码 ThinkPHP框架+Uniapp支持多终端适配部署

在数字化转型浪潮下&#xff0c;企业对高效培训与精准考核的需求日益迫切。一套功能完备、多终端适配且易于定制的培训学习考试系统&#xff0c;成为企业提升员工能力、检验培训成果的关键工具。本文给大家分享一款基于 ThinkPHP 框架与 Uniapp 开发的企业培训学习考试系统&…

【PmHub面试篇】PmHub集成Redission分布式锁保障流程状态更新面试专题解析

你好&#xff0c;欢迎来到本次关于PmHub整合TransmittableThreadLocal (TTL)缓存用户数据的面试系列分享。在这篇文章中&#xff0c;我们将深入探讨这一技术领域的相关面试题预测。若想对相关内容有更透彻的理解&#xff0c;强烈推荐参考之前发布的博文&#xff1a;【PmHub后端…

mac 设置cursor (像PyCharm一样展示效果)

一、注册 Cursor - The AI Code Editor 二、配置Python环境 我之前使用pycharm创建的python项目&#xff0c;以及创建了虚拟环境&#xff0c;现在要使用cursor继续开发。 2.1 选择Python 虚拟环境 PyCharm 通常将虚拟环境存储在项目目录下的 venv 或 .venv 文件夹中&#xf…

Spring事务失效-----十大常见场景及解决方案全解析

Spring事务失效的常见场景及原因分析 Spring事务管理是开发中的核心功能,但在实际应用中可能因各种原因导致事务失效。以下是常见的事务失效场景及详细解析: 1. 方法未被Spring管理 场景:使用new关键字直接创建对象,而非通过Spring容器注入原因:Spring事务基于AOP代理,…

刚出炉热乎的。UniApp X 封装 uni.request

HBuilder X v4.66 当前最新版本 由于 uniapp x 使用的是自己包装的 ts 语言 uts。目前语言还没有稳定下来&#xff0c;各种不支持 ts 各种报错各种不兼容问题。我一个个问题调通的&#xff0c;代码如下&#xff1a; 封装方法 // my-app/utils/request.uts const UNI_APP_BASE…

【ArcGIS微课1000例】0148:Geographic Imager6.2使用教程

文章目录 一、Geographic Imager6.2下载安装二、Geographic Imager6.2使用方法1. 打开Geographic Imager2. 导入地理影像3. 导入DEM地形渲染4. 设置地理坐标系统5. 进行地理影像的处理6. 导出地理影像一、Geographic Imager6.2下载安装 在专栏上一篇文章中已经详细讲述了Geogr…

零基础安装 Python 教程:从下载到环境配置一步到位(支持 VSCode 和 PyCharm)与常用操作系统操作指南

零基础安装 Python 教程&#xff1a;从下载到环境配置一步到位&#xff08;支持 VSCode 和 PyCharm&#xff09;与常用操作系统操作指南 本文是一篇超详细“Python安装教程”&#xff0c;覆盖Windows、macOS、Linux三大操作系统的Python安装方法与环境配置&#xff0c;包括Pyt…

定时任务的 cron 表达式

定时任务的 cron 表达式 一、什么时 cron 表达式 Cron表达式是一种广泛应用于Linux系统的时间表示格式&#xff0c;常用于定时任务的调度。Cron表达式可以通过指定不同的时间参数&#xff0c;描述一个在 未来某个时间点执行的任务。 二、Cron表达式语法 秒 分 时 日 月 周几…