還不理解springAOP系列第三篇,帶你學習spring的面向切面程式設計之環繞通知<aop:around/>
阿新 • • 發佈:2020-12-24
技術標籤:AOPspring面向切面程式設計aop面向切面程式設計環繞通知
在第二篇中,我們已經學習了前置通知和後置通知等,本篇主要講解環繞通知,環繞通知相對於前置和後置通知來說,有明顯的優勢。使用環繞通知,我們可以完成前置通知和後置通知所實現的相同功能,而且只需在一個方法中實現。因為整個通知邏輯是在一個方法內實現的,所以不需要使用多個方法。
環繞通知在XML檔案中的配置方法與其他型別通知沒有太大差異,我們只需使用<aop:around>標籤,同時,指定切點和通知方法的名字即可。如下:
<?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/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="accountService" class="cn.com.lzxh.service.impl.AccountServiceImpl"></bean> <!-- 註冊日誌bean --> <bean id="logger" class="cn.com.lzxh.utils.Logger"></bean> <!-- 配置AOP --> <aop:config> <aop:pointcut id="expre" expression="execution(public void cn.com.lzxh.service.impl.AccountServiceImpl.saveAccount())"/> <!-- 配置切面 --> <aop:aspect id="aspect" ref="logger"> <!-- 配置環繞通知 --> <aop:around method="arroundLog" pointcut-ref="expre"/> </aop:aspect> </aop:config> <!-- 加入以下配置,防止spring AOP代理混用導致異常 --> <aop:aspectj-autoproxy proxy-target-class="true"/> </beans>
但是,環繞通知的方法必須接收一個ProceedingJoinPoint型別的形參,ProceedingJoinPoint是spring提供的一個介面,這個介面有一個proceed()方法,呼叫這個方法就相當於呼叫了切點方法。否則,使用環繞通知時,程式只會執行環繞通知的內容,不會執行切點方法。程式碼如下:
package cn.com.lzxh.utils; import org.aspectj.lang.ProceedingJoinPoint; public class Logger { //環繞通知 public void arroundLog(ProceedingJoinPoint pjp) { Object[] args = pjp.getArgs(); try { System.out.println("前置通知"); pjp.proceed(args); System.out.println("後置通知"); } catch (Throwable e) { System.out.println("異常通知"); e.printStackTrace(); } finally { System.out.println("最終通知"); } } }
實現類:
package cn.com.lzxh.service.impl;
import cn.com.lzxh.service.AccountService;
public class AccountServiceImpl implements AccountService {
@Override
public void saveAccount() {
System.out.println("儲存資料。。。");
}
}
測試類:
package cn.com.lzxh.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.com.lzxh.service.AccountService; import cn.com.lzxh.service.impl.AccountServiceImpl; public class TestAOP { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml"); AccountService as = ac.getBean("accountService", AccountServiceImpl.class); as.saveAccount(); } }
執行結果為: