Spring基于注解的AOP配置

https://blog.csdn.net/qq_40794973/article/details/90313894
pom.xml

<!--spring 的任何部分的運(yùn)行都需要ioc的支持-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.2.RELEASE</version>
</dependency>

<!--AOP解析切入點(diǎn)表達(dá)式-->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.7</version>
</dependency>

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>

賬戶的業(yè)務(wù)層接口

package com.itheima.service;

/**
 * 賬戶的業(yè)務(wù)層接口
 *  下面有三個(gè)不同類型的方法
 */
public interface IAccountService {
    /**
     * 模擬保存賬戶
     */
    void saveAccount();
}

賬戶的業(yè)務(wù)層接口實(shí)現(xiàn)

package com.itheima.service.impl;
import com.itheima.service.IAccountService;
import org.springframework.stereotype.Service;

/**
 * 賬戶的業(yè)務(wù)層實(shí)現(xiàn)類
 */
@Service("accountService")
public class AccountServiceImpl implements IAccountService{
    @Override
    public void saveAccount() {
        System.out.println("執(zhí)行了保存");
    }
}

用于記錄日志的工具類,它里面提供了公共的代碼

package com.itheima.utils;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * 公共代碼類
 * 用于記錄日志的工具類,它里面提供了公共的代碼
 */
@Component("logger")
@Aspect//表示當(dāng)前類是一個(gè)切面類
public class Logger {

    @Pointcut("execution(* com.itheima.service.impl.*.*(..))")
    private void pt1(){}
    /**
     * 前置通知
     */
    @Before("pt1()")
    public  void beforePrintLog(){
        System.out.println("前置通知Logger類中的beforePrintLog方法開始記錄日志了。。。");
    }
    /**
     * 后置通知
     */
    @AfterReturning("pt1()")
    public  void afterReturningPrintLog(){
        System.out.println("后置通知Logger類中的afterReturningPrintLog方法開始記錄日志了。。。");
    }
    /**
     * 異常通知
     */
    @AfterThrowing("pt1()")
    public  void afterThrowingPrintLog(){
        System.out.println("異常通知Logger類中的afterThrowingPrintLog方法開始記錄日志了。。。");
    }
    /**
     * 最終通知
     */
    @After("pt1()")
    public  void afterPrintLog(){
        System.out.println("最終通知Logger類中的afterPrintLog方法開始記錄日志了。。。");
    }
    /**
     * 環(huán)繞通知
     * 問(wèn)題:
     *      當(dāng)我們配置了環(huán)繞通知之后,切入點(diǎn)方法沒(méi)有執(zhí)行,而通知方法執(zhí)行了。
     * 分析:
     *      通過(guò)對(duì)比動(dòng)態(tài)代理中的環(huán)繞通知代碼,發(fā)現(xiàn)動(dòng)態(tài)代理的環(huán)繞通知有明確的切入點(diǎn)方法調(diào)用,而我們的代碼中沒(méi)有。
     * 解決:
     *      Spring框架為我們提供了一個(gè)接口:ProceedingJoinPoint。該接口有一個(gè)方法proceed(),此方法就相當(dāng)于明確調(diào)用切入點(diǎn)方法。
     *      該接口可以作為環(huán)繞通知的方法參數(shù),在程序執(zhí)行時(shí),spring框架會(huì)為我們提供該接口的實(shí)現(xiàn)類供我們使用。
     *
     * spring中的環(huán)繞通知:
     *      它是spring框架為我們提供的一種可以在代碼中手動(dòng)控制增強(qiáng)方法何時(shí)執(zhí)行的方式。
     */
    //@Around("pt1()")
    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ù)層方法(切入點(diǎn)方法)

            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方法開始記錄日志了。。。最終");
        }
    }
}

測(cè)試

import com.itheima.service.IAccountService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringTest {
    /**
     * 測(cè)試AOP的配置
     */
    @Test
    public void testAOP() {
        //1.獲取容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("ApplicationContext1.xml");
        //2.獲取對(duì)象
        IAccountService as = (IAccountService) ac.getBean("accountService");
        //3.執(zhí)行方法
        as.saveAccount();
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容