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
繁體地址,請注明出處:http://hk.pswp.cn/diannao/85816.shtml
英文地址,請注明出處:http://en.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表達式語法 秒 分 時 日 月 周幾…