Spring基于XML文件配置AOP

AOP

AOP,面向切面編程,是對面向對象編程OOP的升華。OOP是縱向對一個事物的抽象,一個對象包括靜態的屬性信息,包括動態的方法信息等。而AOP是橫向的對不同事物的抽象,屬性與屬性、方法與方法、對象與對象都可以組成一個切面,而用這種思維去設計編程的方式叫做面向切面編程

AOP思想的實現方案:動態代理技術,在運行期間,對目標對象的方法進行增強,代理對象同名方法內可以執行原有邏輯的同時嵌入執行其他增強邏輯或其他對象的方法

下面是AOP的實現思想

創建增強類,編寫前方法與后方法

public class MyAdvice {public void beforeAdvice(){System.out.println("執行增強前方法");}public void afterAdvice(){System.out.println("執行增前后方法");}
}

編寫被增強類,并編寫一個方法用于增強

public class UserServiceImpl implements UserService {@Overridepublic void show() {System.out.println("show...");}}

Bean后處理器去實現將Bean對象替換成代理類

public class MyBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware {private ApplicationContext context;@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {//對指定方法進行增強if (bean instanceof UserService) {//獲取增強方法MyAdvice myAdvice = context.getBean(MyAdvice.class);Object proxyInstance = Proxy.newProxyInstance(bean.getClass().getClassLoader(),bean.getClass().getInterfaces(),new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {myAdvice.beforeAdvice();method.invoke(bean, args);myAdvice.afterAdvice();return proxy;}});return proxyInstance;}return bean;}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.context = applicationContext;}
}

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/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><bean id="userService" class="com.zmt.service.impl.UserServiceImpl"></bean><bean class="com.zmt.processor.MyBeanPostProcessor"/><bean class="com.zmt.advice.MyAdvice"/>
</beans>

執行測試代碼

public class ApplicationTest {public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application.xml");UserService userService = context.getBean(UserService.class);userService.show();}
}

執行結果如下?

這種實現方式存在兩個問題,一個是需要被增強的Bean對象需要硬編碼指定,其次是增強方法也是被寫死的,如果需要修改被增強的類或是修改增強方法都需要修改代碼。

那么我們在了解Spring中AOP時,需要先了解如下幾個概念

目標對象

Taeget

被增強的方法所在的對象

代理對象

Proxy

對目標方法進行增強后的對象,客戶端實際調用的對象

連接點

Joinpoint

目標對象中可以被增強的方法

切入點

Pointcut

目標對象中實際被增強的方法

通知\增強

Advice

增強部分的代碼邏輯

切面

Aspect

增強和切入點的組合

織入

Weaving

將通知和切入點動態組合的過程

那么接下來給出基于XML的實現AOP的示例代碼

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"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"><bean id="userService" class="com.zmt.service.impl.UserServiceImpl"/><!--將增強類交給Spring管理--><bean id="myAdvice" class="com.zmt.advice.MyAdvice"/><aop:config><!--配置切面表達式,指定需要被增強的方法--><aop:pointcut id="myPointcut" expression="execution(void com.zmt.service.impl.UserServiceImpl.show())"/><!--指定切點與哪些增強類結合--><aop:aspect ref="myAdvice"><aop:before method="beforeAdvice" pointcut-ref="myPointcut"/></aop:aspect></aop:config>
</beans>
public class UserServiceImpl implements UserService {@Overridepublic void show() {System.out.println("show...");}}
public class MyAdvice {public void beforeAdvice(){System.out.println("執行增強前方法");}public void afterAdvice(){System.out.println("執行增前后方法");}
}

測試代碼如下

public class ApplicationTest {public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application.xml");UserService userService = context.getBean(UserService.class);userService.show();}
}

運行結果如下

execution語法

execution([訪問修飾符] 返回值類型 報名.類名.方法名(參數))

  • 訪問修飾符可以省略不寫
  • 返回值類型、某一級包名、類名、方法名可以使用 * 表示任意
  • 包名與類名之間使用單點 . 表示該包下的類,使用雙點 .. 表示該包以及子包下的類
  • 參數列表可以使用雙點 .. 表示任意參數

XML文件下通知的配置類型

通知名稱

配置方式

執行時機

前置通知

< aop:before >

目標方法執行之前執行

后置通知

< aop:after-returning >

目標方法執行之后執行,目標方法異常時不再執行

環繞通知

< aop:around >

目標方法執行前后執行,目標方法異常時,環繞后方法不再執行

異常通知

< aop:after-throwing >

目標方法拋出異常時執行

最終通知

< aop:after >

不管目標方法是否有異常,最終都會執行

環繞通知需要將連接點傳入,具體的增強類實現代碼如下

public class MyAdvice {public void beforeAdvice(){System.out.println("執行增強前方法");}public void afterAdvice(){System.out.println("執行增前后方法");}public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("環繞前通知。。。");Object proceed = joinPoint.proceed();System.out.println("環繞后通知。。。");return proceed;}
}

增強方法在被調用時,Spring可以為其傳遞一些必要參數

參數類型

作用

JoinPoint

連接點對象,任何通知都可以使用,可以獲取當前目標對象,目標方法參數等信息

ProceedingJoinPoint

JoinPoint子類對象,主要是在環繞通知中執行proceed(),進而執行目標方法

Throwable

異常對象,使用在異常通知中,需要在配置文件中指出異常對象名稱

除了上面實現AOP之外,基于XML文件配置的實現方式還存在另一種實現方式,通過實現接口來表示該增強類的具體操作。

public class MyAdvice2 implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {System.out.println("環繞前通知。。。。");Object res = invocation.getMethod().invoke(invocation.getThis(), invocation.getArguments());System.out.println("環繞后通知。。。。");return res;}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"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"><bean id="userService" class="com.zmt.service.impl.UserServiceImpl"/><bean id="myAdvice2" class="com.zmt.advice.MyAdvice2"/><aop:config><aop:pointcut id="myPointcut" expression="execution(void com.zmt.service.impl.UserServiceImpl.show())"/><!-- 指定增強類與切點 --><aop:advisor advice-ref="myAdvice2" pointcut-ref="myPointcut"/></aop:config>
</beans>

注意:一個增強類可以實現多個Advice接口

AOP配置的兩種語法形式不同點

語法形式不同:

  • advisor是通過實現接口來確認通知的類型
  • aspect是通過配置確認通知的類型,更加靈活

可配置的切面數量不同:

  • 一個advisor只能配置一個固定通知和一個切點表達式
  • 一個aspect可以配置多個通知和多個切點表達式任意組合

使用場景不同:

  • 允許隨意搭配情況下可以使用aspect進行配置
  • 如果通知類型單一、切面單一的情況下可以使用advisor進行配置
  • 在通知類型已經固定,不用人為指定通知類型時,可以使用advisor進行配置

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/211555.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/211555.shtml
英文地址,請注明出處:http://en.pswp.cn/news/211555.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

12.10多種編碼方式,編碼方案選擇策略(遞歸級聯),PDE,RLE代碼

作者如何選擇和設計編碼方案&#xff0c;以實現高效的解壓縮和高壓縮比&#xff1f;BtrBlocks是否適用于所有類型的數據&#xff1f; 選擇和設計編碼方案&#xff1a; 結合多種高效編碼方案&#xff1a;BtrBlocks 通過選擇一組針對不同數據分布的高效編碼方案&#xff0c;實現…

js判斷是否對象自身為空

文章目錄 一、前言二、JSON.stringify三、for in 配合 hasOwnProperty四、Object.keys五、Object.getOwnPropertyNames六、Object.getOwnPropertyNames 結合 Object.getOwnPropertySymbols七、Reflect.ownKeys八、最后 一、前言 如何判斷一個對象為空&#xff1f; 先上結論&a…

MySql復習筆記03(小滴課堂) 事務,視圖,觸發器,存儲過程

mysql 必備核心知識之事務的詳細解析&#xff1a; 創建一個數據庫表&#xff1a; 添加數據并開啟事務。 添加數據并查詢。 登錄另一臺服務器發現查不到這個表中的數據。 這是因為事務開啟了&#xff0c;但是沒有提交&#xff0c;只是把數據存到了內存中&#xff0c;還沒有寫入…

以為回調函數是同步的(js的問題)

回調函數可以用來處理 JavaScript 的異步操作&#xff0c;但是選用 Promise、async/await 更好&#xff0c;因為多重回調函數會導致回調地獄。 回調函數不是**同步的**&#xff0c;它是延時操作執行完畢后會被調用的一個函數。 比如全局方法 "setTimeout" &#xf…

CString 的 Replace 函數

Replace 使用測試 CString mSectNameNew L"槽a*b*c*d";CString mSectNameNew2 L"Ca*b*c*d";CString mSectNameNew3 L"[a*b*c*d";mSectNameNew.Replace(_T("M"), _T("C")); // 不會替換mSectNameNew.Re…

JOSEF 沖擊繼電器 ZC-23A DC48V 柜內安裝,板前帶座

系列型號 ZC-23沖擊繼電器&#xff1b;ZC-23A沖擊繼電器&#xff1b; ZC-23B沖擊繼電器 一、用途 沖擊繼電器ZC-23A DC48V 柜內安裝板前帶座 (以下簡稱繼電器)&#xff0c;廣泛用于直流操作的繼電器保護及自動控制回路中&#xff0c;作為集中控制信號元件。 二、主要技術參…

C#動態調用C++DLL中的函數

DLL中導出的函數 typedef void (*HQ_MSG_CALLBACK)(void *h, int nMsg, int nMsgType, int nReqNo, const char *szData, int nSize); void SetMsgFunc(void *h, HQ_MSG_CALLBACK pmsgCallBack);C#動態調用上述函數 public delegate void CALLBACK(IntPtr h, int nMsg, int n…

信息處理技術員

目錄 信息處理技術員工作內容 信息處理技術員崗位面試試題舉例 信息處理技術員考試 信息處理技術員工作內容 信息處理技術員是負責處理和管理信息系統的專業人員。他們的主要工作內容包括以下幾個方面&#xff1a; 1.系統維護和管理&#xff1a;信息處理技術員負責維護和管…

大數據股票簡單分析

目錄標題 內容說明解題量化金融的含義量化交易策略 點擊直接資料領取 內容 1解釋量化金融的含義&#xff0c;調研并給出至少 5種量化交易的策略或方法 2.完成Tushare Pro 的安裝、注冊&#xff0c;獲取自己的 Token&#xff0c;查閱網站內的接口講解和示例; 3通過Python 編程完…

力扣刷題總結 字符串(2)【KMP】

&#x1f525;博客主頁&#xff1a; A_SHOWY&#x1f3a5;系列專欄&#xff1a;力扣刷題總結錄 數據結構 云計算 數字圖像處理 28.找出字符串中第一個匹配項的下標mid經典KMP4593重復的子字符串mid可以使用滑動窗口或者KMP KMP章節難度較大&#xff0c;需要深入理解其中…

Flink 本地單機/Standalone集群/YARN模式集群搭建

準備工作 本文簡述Flink在Linux中安裝步驟&#xff0c;和示例程序的運行。需要安裝JDK1.8及以上版本。 下載地址&#xff1a;下載Flink的二進制包 點進去后&#xff0c;選擇如下鏈接&#xff1a; 解壓flink-1.10.1-bin-scala_2.12.tgz&#xff0c;我這里解壓到soft目錄 [ro…

OrangePi ZERO2 刷機與啟動

鏡像準備 用讀卡器和Win32Diskimager刷寫鏡像到內存卡&#xff0c;鏡像文件見下面百度云鏈接&#xff1a;https://pan.baidu.com/s/14aKTznc4Jvw4SoFF54JUTg 提取碼&#xff1a;1815 刷寫完畢后插回香橙派 串口登錄 用MobaXterm和USB-TTL進行串口登錄&#xff0c;MobaXterm軟…

談一談網絡協議中的應用層

文章目錄 一&#xff0c;什么是HTTPHTTP的優缺點HTTPS 一&#xff0c;什么是HTTP 我們在通過網絡進行傳輸數據時&#xff0c;我們要保證&#xff0c;我們在發送時構造的數據&#xff0c;在接收時也能夠解析出來&#xff0c;這本質上就是一種協議&#xff0c;是一種應用層協議&…

Spring Cloud + Vue前后端分離-第3章 SpringBoot項目技術整合

Spring Cloud Vue前后端分離-第3章 SpringBoot項目技術整合 3-1 集成持久層框架Mybatis ORM:對象關系映射&#xff0c;Hibernate是全自動ORM&#xff0c;Mybatis是半自動ORM&#xff0c;Mybatis可以操作的花樣更多&#xff0c;是首選的持久層框架 System模塊集成Mybatis框架…

整數分析 C語言xdoj43

問題描述 給出一個整數n&#xff08;0<n<100000000&#xff09;。求出該整數的位數&#xff0c;以及組成該整數的所有數字中的最大數字和最小數字。 輸入說明 輸入一個整數n&#xff08;0<n<100000000&#xff09; 輸出說明 在一行上依次輸出整數n的位…

Linux內核上游提交完整流程及示例

參考博客文章&#xff1a; 向linux內核提交代碼 - 知乎 一、下載Linux內核源碼 通過git下載Linux內核源碼&#xff0c;具體命令如下&#xff1a; git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 實際命令及結果如下&#xff1a; penghaoDin…

IBM Qiskit量子機器學習速成(六)

量子卷積神經網絡 卷積和池化&#xff1a;卷積神經網絡的必備成分 卷積神經網絡被廣泛應用于圖像和音頻的識別當中&#xff0c;關鍵在于“卷積”操作賦予神經網絡統籌學習數據的能力。 執行卷積操作需要輸入數據與卷積核&#xff0c;卷積核首先與輸入數據左上角對齊&#xf…

【數據庫】簡單連接嵌套查詢

目錄 &#x1f387;簡單查詢 &#x1f387;連接查詢 &#x1f387;嵌套查詢 分析&思考 &#x1f387;簡單查詢 --練習簡單查詢 --select * from classes --select * from student --select * from scores --1.按Schedule表的結構要求用SQL語言創建Schedule表 --字段名…

深度學習之全面了解預訓練模型

在本專欄中&#xff0c;我們將討論預訓練模型。有很多模型可供選擇&#xff0c;因此也有很多考慮事項。 這次的專欄與以往稍有不同。我要回答的問題全部源于 MathWorks 社區論壇&#xff08;ww2.mathworks.cn/matlabcentral/&#xff09;的問題。我會首先總結 MATLAB Answers …

關于Linux Kernel Panic導致重啟的簡單分析步驟

Linux系統Kernel Panic的檢索 如何判斷是否發生Kernel Panic&#xff0c;以下以 CentOS 7.9系統為例 #查看 /var/crash 路徑下是否有生成文件夾&#xff0c;Kernel Panic后會生成文件夾在此路徑表示產生了Kernel Panic ls /var/crash #/var/crash/127.0.0.1-2023-12-04-08\:5…