中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Spring??AOP如何使用

發布時間:2022-08-12 11:17:18 來源:億速云 閱讀:118 作者:iii 欄目:開發技術

這篇“Spring  AOP如何使用”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Spring  AOP如何使用”文章吧。

1 注解方式

1.1 聲明目標類 UserDao 類

@Repository("userDao")
public class UserDao {

    public void addUser() {
        System.out.println("???? 攔截的方法 addUser 開始執行");
    }
}

1.2 聲明切面 AnnotationAspect 類

@Aspect
@Component
public class AnnotationAspect {

    // 定義切入點表達式, 使用一個返回值為 void、方法體為空的方法來命名切入點
    @Pointcut("execution(* com.fairy.springmvc.aspectj.annotation.*.*(..))")
    private void customPointCut(){}

    // 前置通知
    @Before("customPointCut()")
    public void myBefore(JoinPoint joinPoint){
        System.out.print("前置通知:模擬執行權限檢查..,");
        System.out.print("目標類是:" + joinPoint.getTarget());
        System.out.println(",被植入增強處理的目標方法為:" + joinPoint.getSignature().getName());
    }

    // 后置通知
    @AfterReturning(value="customPointCut()")
    public void myAfterReturning(JoinPoint joinPoint) {
        System.out.print("后置通知:模擬記錄日志..,");
        System.out.println("被植入增強處理的目標方法為:" + joinPoint.getSignature().getName());
    }

    /**
     * 環繞通知
     * ProceedingJoinPoint 是 JoinPoint的子接口,表示可執行目標方法
     * 1.必須是 Object 類型的返回值
     * 2.必須接收一個參數,類型為 ProceedingJoinPoint
     * 3.必須 throws Throwable
     */
    @Around("customPointCut()")
    public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
        // 開始
        System.out.println("環繞開始:執行目標方法之前,模擬開啟事務..,");
        // 執行當前目標方法
        Object obj = proceedingJoinPoint.proceed();
        // 結束
        System.out.println("環繞結束:執行目標方法之后,模擬關閉事務..,");
        return obj;
    }

    /**
     * 異常通知處理
     * @param joinPoint
     * @param e
     */
    @AfterThrowing(value="customPointCut()",throwing="e")
    public void myAfterThrowing(JoinPoint joinPoint, Throwable e){
        System.out.println("異常通知:出錯了" + e.getMessage());
    }

    // 最終通知
    @After("customPointCut()")
    public void myAfter(){
        System.out.println("最終通知:模擬方法結束后釋放資源..");
    }
}

1.3 聲明配置

開啟@AspectJ的注解配置方式,有兩種方式

1 在 xml 文件,添加以下配置:

<!-- 啟動基于注解的聲明式 AspectJ 支持 -->
<aop:aspectj-autoproxy />

2 使用了 Java 代碼風格的配置,則需使用 EnableAspectJAutoProxy 注解

示例如下

@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.fairy.springmvc")
public class ApplicationConfig {
    ....
}

1.4 測試用例

public class TestCase {
    @Test
    public void testAnnotation() throws Exception {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                "spring-test.xml");

        // 從容器中獲得內容
        UserDao userDao= (UserDao) applicationContext.getBean("userDao");
        // 執行方法
        userDao.addUser();
    }
}

運行結果如下:

環繞開始:執行目標方法之前,模擬開啟事務..,
前置通知:模擬執行權限檢查..,
    目標類是:com.fairy.springmvc.aspectj.annotation.UserDao@4a699efa,
    被植入增強處理的目標方法為:addUser
???? 攔截的方法 addUser 開始執行
后置通知:模擬記錄日志..,被植入增強處理的目標方法為:addUser
最終通知:模擬方法結束后釋放資源..
環繞結束:執行目標方法之后,模擬關閉事務..,

通過輸出結果看出,符合預期。

2 XML 配置方式

2.1 聲明目標類 CompanyDao

@Repository("companyDao")
public class CompanyDao {

    public void addCompany() {
        System.out.println("???? 真正的業務處理:add company ????");
    }

    public void exception() throws Exception {
        throw new Exception("業務異常了");
    }
}

2.2 聲明切面攔截類 XmlAspect

@Component("xmlAspectConfig")
public class XmlAspect {

    public void printUnderscore() {
        System.out.println("------------------------------------------------");
    }

    /**
     * 在核心業務執行前執行,不能阻止核心業務的調用
     * @param joinPoint
     */
    public void beforeAdvice(JoinPoint joinPoint) {
        printUnderscore();
        System.out.println("1?? 通知:beforeAdvice 執行開始");
        System.out.println("   執行核心業務邏輯前,可以做一些前置的安全性的檢測等");
        System.out.println("   通知:beforeAdvice 執行結束");
        printUnderscore();
    }

    /**
     * 核心業務退出后,不管是正常結束還是異常退出,均執行此通知
     * @param joinPoint
     */
    public void afterAdvice(JoinPoint joinPoint) {
        printUnderscore();
        System.out.println("4?? 通知:afterAdvice 執行開始");
        System.out.println("   此處可以對返回值做進一步的處理");
        System.out.println("   通知:afterAdvice 執行結束");
    }

    /**
     * 核心業務調用正常退出后,不管是否有返回值,只要是正常退出,都會執行此通知
     * @param joinPoint
     */
    public void afterReturningAdvice(JoinPoint joinPoint) {
        printUnderscore();
        System.out.println("2?? 通知:afterReturningAdvice 執行開始");
        System.out.println("   此處可以對返回值做進一步處理");
        System.out.println("   通知:afterReturningAdvice 執行結束");
    }

    /**
     * 核心業務邏輯調用異常退出后,執行此通知,處理錯誤信息
     * @param e
     */
    public void afterThrowingAdvice(Exception e) {
        printUnderscore();
        System.out.println("3?? 通知:afterThrowingAdvice 執行開始");
        System.out.println("   錯誤信息:" + e.getMessage());
        System.out.println("   此處意味著,在核心業務邏輯出錯時,捕獲異常,并可以做一些日志記錄相關的操作");
    }

    /**
     * 手動控制調用核心業務邏輯,以及調用前和調用后的處理
     * @param pjp
     */
    public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
        // 開始
        System.out.println("5?? 環繞開始:執行目標方法之前");
        System.out.println("   此處可以做類似于 Before Advice 的事情");
        // 調用核心邏輯,執行當前目標方法
        Object obj = pjp.proceed();

        // 打印下劃線
        printUnderscore();
        // 結束
        System.out.println("   此處可以做類似于 After Advice 的事情");
        System.out.println("5?? 環繞結束:執行目標方法之后");
        return obj;
    }
}

2.3 聲明 XML 配置

<!-- 基于 XML 文件的配置進行聲明,注意和 aop:aspectj-autoproxy 的區別 -->
<aop:config proxy-target-class="true">

    <!-- 基于 aspect 配置一個完整的切面 -->
    <aop:aspect id="aspectXmlConfigExample" ref="xmlAspectConfig">
        <!-- 切點配置,可以配置多個切點 -->
        <aop:pointcut id="xmlPointCut"
                      expression="execution(* com.fairy.springmvc.aspectj.xml.CompanyDao.*(..))"/>
        <aop:after-returning method="afterReturningAdvice" pointcut-ref="xmlPointCut" />
        <aop:after-throwing method="afterThrowingAdvice" pointcut-ref="xmlPointCut" throwing="e"/>
        <aop:after method="afterAdvice" pointcut-ref="xmlPointCut" />
        <aop:around method="aroundAdvice" pointcut-ref="xmlPointCut" />
        <aop:before method="beforeAdvice" pointcut-ref="xmlPointCut" />
    </aop:aspect>

</aop:config>

注意:

值得注意的是 around 與 before 和 after 的執行順序。3 者的執行順序取決于在 xml 中的配置順序。

2.3 測試用例

public class TestCase {
    @Test
    public void testAnnotation() throws Exception {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                "spring-test.xml");

        CompanyDao companyDao = (CompanyDao) applicationContext.getBean("companyDao");
        companyDao.addCompany();
        // companyDao.exception();
    }

}

輸出結果如下:

-------------------------------
5?? 環繞開始:執行目標方法之前
   此處可以做類似于 Before Advice 的事情
------------------------------------------------
1?? 通知:beforeAdvice 執行開始
   執行核心業務邏輯前,可以做一些前置的安全性的檢測等
   通知:beforeAdvice 執行結束
------------------------------------------------
???? 真正的業務處理:add company ????
------------------------------------------------
2?? 通知:afterReturningAdvice 執行開始
   此處可以對返回值做進一步處理
   通知:afterReturningAdvice 執行結束
------------------------------------------------
4?? 通知:afterAdvice 執行開始
   此處可以對返回值做進一步的處理
   通知:afterAdvice 執行結束
------------------------------------------------
   此處可以做類似于 After Advice 的事情
5?? 環繞結束:執行目標方法之后

結果符合預期。

以上就是關于“Spring  AOP如何使用”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

米脂县| 白沙| 汝阳县| 青浦区| 文安县| 佛教| 鹤庆县| 淮滨县| 伊金霍洛旗| 金秀| 星子县| 隆尧县| 九龙县| 鞍山市| 永顺县| 锡林郭勒盟| 桐梓县| 黎平县| 乌拉特前旗| 泰和县| 郑州市| 湖南省| 武定县| 遵义县| 民县| 峡江县| 静安区| 新建县| 乌兰浩特市| 东平县| 临西县| 兰坪| 甘孜县| 徐汇区| 延安市| 陆河县| 黑河市| 平武县| 土默特左旗| 南投县| 克山县|