亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

SpringAOP四種通知類型+環(huán)繞通知說明

 更新時間:2021年09月07日 09:13:25   作者:晚點喝可樂z  
這篇文章主要介紹了SpringAOP四種通知類型+環(huán)繞通知說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

SpringAOP的四種通知類型:前置通知、異常通知、后置通知、異常通知

一、四種常見的通知類型

給出 賬戶的業(yè)務(wù)層接口 IAccountService.java,

為了便于演示這四種通知類型,我們就只留下了一個方法。

public interface IAccountService {
   void saveAccount();
}

給出 賬戶的業(yè)務(wù)層接口的實現(xiàn)類 AccountServiceImpl.java

public class AccountServiceImpl implements IAccountService{
    @Override
    public void saveAccount() {
        System.out.println("執(zhí)行了保存");
        //int i=1/0;
    }
}

給出一個日志類, 用于打印日志

public class Logger {
    /**
     * 前置通知
     */
    public  void beforePrintLog(){
        System.out.println("前置通知Logger類中的beforePrintLog方法開始記錄日志了。。。");
    }
    /**
     * 后置通知
     */
    public  void afterReturningPrintLog(){
        System.out.println("后置通知Logger類中的afterReturningPrintLog方法開始記錄日志了。。。");
    }
    /**
     * 異常通知
     */
    public  void afterThrowingPrintLog(){
        System.out.println("異常通知Logger類中的afterThrowingPrintLog方法開始記錄日志了。。。");
    }
    /**
     * 最終通知
     */
    public  void afterPrintLog(){
        System.out.println("最終通知Logger類中的afterPrintLog方法開始記錄日志了。。。");
    }
}

給出配置信息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/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">
    <!-- 配置srping的Ioc,把service對象配置進來-->
    <bean id="accountService" class="service.AccountServiceImpl"></bean>
    <!-- 配置Logger類 -->
    <bean id="logger" class="utils.Logger"></bean>
    <!--配置AOP-->
    <aop:config>
      <!--配置切入點表達式 -->
        <aop:pointcut id="pt1" expression="execution(* service.AccountServiceImpl.saveAccount())"></aop:pointcut>
        <!--配置切面 -->
        <aop:aspect id="logAdvice" ref="logger">
            <!-- 配置前置通知:在切入點方法執(zhí)行之前執(zhí)行-->
            <aop:before method="beforePrintLog" pointcut-ref="pt1" ></aop:before>
            <!-- 配置后置通知:在切入點方法正常執(zhí)行之后值-->
            <aop:after-returning method="afterReturningPrintLog" pointcut-ref="pt1"></aop:after-returning>
            <!-- 配置異常通知:在切入點方法執(zhí)行產(chǎn)生異常之后執(zhí)行-->
            <aop:after-throwing method="afterThrowingPrintLog" pointcut-ref="pt1"></aop:after-throwing>
            <!-- 配置最終通知:無論切入點方法是否正常執(zhí)行它都會在其后面執(zhí)行-->
            <aop:after method="afterPrintLog" pointcut-ref="pt1"></aop:after>
            
        </aop:aspect>
    </aop:config>
</beans>

注意

1)異常通知和后置通知永遠只能執(zhí)行一個

2)配置切入點表達式

此標簽寫在aop:aspect標簽內(nèi)部只能當前切面使用。

它還可以寫在aop:aspect外面,此時就變成了所有切面可用

給出Test類

public class AOPTest {
    public static void main(String[] args) {
        //1.獲取容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //2.獲取對象
        IAccountService as = (IAccountService)ac.getBean("accountService");
        //3.執(zhí)行方法
       as.saveAccount();
    }
}

執(zhí)行結(jié)果:

在這里插入圖片描述

當我們放開AccountServiceImpl類中我們故意制造的異常 int i=1/0;時:

在這里插入圖片描述

二、環(huán)繞通知

環(huán)繞通知,只需要稍稍微改變上面例子的兩點即可

1、改動日志類 Logger.java

public class Logger {
    public Object aroundPringLog(ProceedingJoinPoint pjp){
        Object rtValue = null;
        try{
            Object[] args = pjp.getArgs();//得到方法執(zhí)行所需的參數(shù)
            System.out.println("Logger類中的aroundPringLog方法開始記錄日志了。。。前置");
            rtValue = pjp.proceed(args);//明確調(diào)用業(yè)務(wù)層方法(切入點方法)
            System.out.println("Logger類中的aroundPringLog方法開始記錄日志了。。。后置");
            return rtValue;
        }catch (Throwable t){
            System.out.println("Logger類中的aroundPringLog方法開始記錄日志了。。。異常");
            throw new RuntimeException(t);
        }finally {
            System.out.println("Logger類中的aroundPringLog方法開始記錄日志了。。。最終");
        }
    }
}

注意:pjp.proceed(args)會報異常,必須用 Throwable t,因為Exception攔不住它

2、改動配置文件

<?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
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- 配置srping的Ioc,把service對象配置進來-->
    <bean id="accountService" class="service.AccountServiceImpl"></bean>
    <!-- 配置Logger類 -->
    <bean id="logger" class="utils.Logger"></bean>
    <!--配置AOP-->
    <aop:config>
    	<!--配置切入點表達式 -->
        <aop:pointcut id="pt1" expression="execution(* service.AccountServiceImpl.saveAccount())"></aop:pointcut>
        <!--配置切面 -->
        <aop:aspect id="logAdvice" ref="logger">
            <!-- 配置環(huán)繞通知 詳細的注釋請看Logger類中-->
            <aop:around method="aroundPringLog" pointcut-ref="pt1"></aop:around>
        </aop:aspect>
    </aop:config>
</beans>

分析

  • spring中的環(huán)繞通知是spring框架為我們提供的一種可以在代碼中手動控制增強方法何時執(zhí)行的方式。
  • Spring框架為我們提供了一個接口:ProceedingJoinPoint。該接口有一個方法proceed(),此方法就相當于明確調(diào)用切入點方法。該接口可以作為環(huán)繞通知的方法參數(shù),在程序執(zhí)行時,spring框架會為我們提供該接口的實現(xiàn)類供我們使用。

AOP機制之環(huán)繞通知的見解

我們都知道,AOP機制的核心是在不修改源碼的基礎(chǔ)上對業(yè)務(wù)層方法的增強。

其中有五個通知類型

  • 1、前置通知:在切入點方法之前執(zhí)行
  • 2、后置通知:在切入點方法之后通知
  • 3、異常通知:在執(zhí)行切入點方法過程中出現(xiàn)異常后執(zhí)行(因此異常通知和后置通知只能執(zhí)行一個)
  • 4、最終通知:無論切入點方法是否正常執(zhí)行它都會執(zhí)行
  • 5、環(huán)繞通知: 當配置環(huán)繞通知之后,在環(huán)繞通知里面必須要明確調(diào)用業(yè)務(wù)層的方法,如果不調(diào)用,就會出現(xiàn)只出現(xiàn)通知,而不執(zhí)行方法。其中原理和動態(tài)代理是一樣的,代碼如下。
public AccountService getAccountService() {
        return (AccountService) Proxy.newProxyInstance(accountService.getClass().getClassLoader(), accountService.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                Object rtValue=null;
                try {
                    //1、開啟事務(wù)
                    txManager.beginTransaction();
                    //2、執(zhí)行操作,整個過程像對每個方法進行了包裝,并返回新的accountService對象
                    rtValue=method.invoke(accountService,objects);
                    //3、提交事務(wù)
                    txManager.commit();
                    //4、返回結(jié)果
                    return rtValue;
                }catch (Exception e){
                    //5、回滾事務(wù)
                    txManager.rollback();
                    throw new RuntimeException(e);
                }finally {
                    //6、釋放連接
                    txManager.release();
                }
            }
        });
    }

如果不明確調(diào)用業(yè)務(wù)層方法,就像一個畫皮,沒有發(fā)揮本質(zhì)的作用。

除此之外,我認為環(huán)繞通知可以代替其他的四個通知,

public Object aroundPrintLog(ProceedingJoinPoint pjp){//環(huán)繞通知是不是能夠代替其他的通知
        Object rtvalue=null;
        try {
            /**
             *這里的一切都是為都是給業(yè)務(wù)層方法進行增強,例如:把那些方法拿過來,然后核心的還是rtvalue=pjp.proceed(args),
             *其他的輸出只不過是為核心的業(yè)務(wù)層方法進行修飾
             */
            Object[] args=pjp.getArgs();//得到方法執(zhí)行所需的參數(shù)
            System.out.println("前置通知");
            rtvalue=pjp.proceed(args);//明確調(diào)用業(yè)務(wù)層方法
            System.out.println("后置通知");
            return rtvalue;
        }catch (Throwable e){
            System.out.println("異常通知");
            throw new RuntimeException(e);
        }finally {
            System.out.println("最終通知");
        }
    }

這個屬于典型的環(huán)繞通知,其中把輸出方法換成相應(yīng)的通知方法就可以(有不同觀點的可以說出來一起討論)。

最后,分享一下我學(xué)這個知識的方法。方法增強,本質(zhì)上就是對源碼不修改的情況下進行方法的加工。就好像烤羊肉串一樣,其中的核心就是羊肉,就像公司給你的業(yè)務(wù)層方法(這個是不讓修改的)。在給顧客使用前,收先對羊肉進行刷油、烤、撒料一系列過程,這一過程就是我們對業(yè)務(wù)層方法的增強,使業(yè)務(wù)層的功能更加健壯,對應(yīng)的燒烤也就是更美味。核心的一點就是正確調(diào)用業(yè)務(wù)層的方法,不管在哪類通知中,都能對業(yè)務(wù)層方法進行正確、有效地增強

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • springboot+quartz以持久化的方式實現(xiàn)定時任務(wù)的代碼

    springboot+quartz以持久化的方式實現(xiàn)定時任務(wù)的代碼

    這篇文章主要介紹了springboot+quartz以持久化的方式實現(xiàn)定時任務(wù)的相關(guān)知識,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • Java之單例模式實現(xiàn)方案詳解

    Java之單例模式實現(xiàn)方案詳解

    這篇文章主要介紹了Java之單例模式實現(xiàn)方案詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • 基于Springboot的漫畫網(wǎng)站平臺設(shè)計與實現(xiàn)

    基于Springboot的漫畫網(wǎng)站平臺設(shè)計與實現(xiàn)

    本文將基于Springboot實現(xiàn)開發(fā)一個漫畫主題的網(wǎng)站,實現(xiàn)一個比漂亮的動漫連載的網(wǎng)站系統(tǒng),界面設(shè)計優(yōu)雅大方,比較適合做畢業(yè)設(shè)計和課程設(shè)計使用,需要的可以參考一下
    2022-08-08
  • Java優(yōu)雅的處理金錢問題(BigDecimal)

    Java優(yōu)雅的處理金錢問題(BigDecimal)

    本文主要介紹了Java優(yōu)雅的處理金錢問題(BigDecimal),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Java圖形用戶界面之列表框

    Java圖形用戶界面之列表框

    列表框通過Swing組件JList產(chǎn)生,其總是在屏幕上占據(jù)固定行數(shù)的空間。這篇文章主要介紹了java圖形用戶界面之列表框的相關(guān)資料,非常不錯具有參考借鑒價值,需要的朋友可以參考下
    2016-10-10
  • Java枚舉類型enum的詳解及使用

    Java枚舉類型enum的詳解及使用

    這篇文章主要介紹了Java枚舉類型enum的詳解及使用的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • spring cloud 配置中心native配置方式

    spring cloud 配置中心native配置方式

    這篇文章主要介紹了spring cloud 配置中心native配置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java中IO流文件讀取、寫入和復(fù)制的實例

    Java中IO流文件讀取、寫入和復(fù)制的實例

    下面小編就為大家?guī)硪黄狫ava中IO流文件讀取、寫入和復(fù)制的實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • 簡單了解JAVA中類、實例與Class對象

    簡單了解JAVA中類、實例與Class對象

    這篇文章主要介紹了簡單了解JAVA中類、實例與Class對象,類是面向?qū)ο缶幊陶Z言的一個重要概念,它是對一項事物的抽象概括,可以包含該事物的一些屬性定義,以及操作屬性的方法,需要的朋友可以參考下
    2019-06-06
  • springboot之如何同時連接多個redis

    springboot之如何同時連接多個redis

    這篇文章主要介紹了springboot之如何同時連接多個redis問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04

最新評論