Spring AOP -- 使用 Aspectj

Spring AOP – 使用 Aspectj

        使用 Aspectj 註解實現各種通知

@Before:前置通知,在方法執行前執行
@After:後置通知,在方法執行後通知
@AfterRunning:返回通知,在方法返回結果後通知
@AfterThrowing:異常通知:在方法拋出異常後通知
@Around:環繞通知:圍繞着方法執行

需要以下jar包

		<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        
        <dependency>
            <groupId>aopalliance</groupId>
            <artifactId>aopalliance</artifactId>
            <version>1.0</version>
        </dependency>
        
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${aspectjrt.version}</version>
        </dependency>

創建接口與實現類,並交給 Spring 管理

public interface ArithmeticCalculator {
    int add(int i, int j);
    int div(int i, int j);
}
@Component
public class ArithmeticCalculatorImpl implements ArithmeticCalculator {

    @Override
    public int add(int i, int j) {
        int result = i + j;
        System.out.println("result:" + result);
        return result;
    }

    @Override
    public int div(int i, int j) {
        int result = i / j;
        System.out.println("result:" + result);
        return result;
    }
}

在Spirng配置里加入:

<!-- 配置自動掃描的包 -->
<context:component-scan base-package="com.java.spring.aop"></context:component-scan>

      使用 Aspectj 註解來實現前置通知

//把該類聲明爲一個切面:需要先將類放入到 IOC 容器中 ,再聲明爲一個切面
@Aspect
@Component
public class Logging {
    /*
        聲明該方法是一個 前置通知:在目標方法開始前執行
        execution(* com.java.spring.aop.impl.*.*()) 中表示任意修飾符,任意返回值,
        在com.java.spring.aop.impl 包下任意類中的任意方法
     */
    @Before("execution(* com.java.spring.aop.impl.*.*(int,int))")
    //可以在方法裏聲明類型爲 JoinPoint 的參數,獲得連接點的細節,如方法名稱和參數值
    public void beforLogin(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName(); //獲取方法名稱
        List<Object> args = Arrays.asList(joinPoint.getArgs()); //獲取方法參數值

        System.out.println("method " + methodName + " begins " + args);
    }
}

      執行結果如下

 method add begins [3, 6]
 result:9
 method div begins [12, 3]
 result:4

      使用 Aspectj 註解來實現後置通知

//在方法執行後,執行通知(無論是否發送異常)
    @After("execution(* com.java.spring.aop.impl.*.*(int,int))")
    public void afterLogin(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();

        System.out.println("method " + methodName);
    }

      執行結果如下

 result:9
 method add end 
 result:4
 method div end 

注意:即便發生異常,依然會執行:
在這裏插入圖片描述

      使用 Aspectj 註解來實現返回通知

	//在方法正常結束後執行,可以訪問到方法的返回值
    @AfterReturning(value = "execution(* com.java.spring.aop.impl.*.*(int,int))",returning = "result")
    public void afterReturningLogin(JoinPoint joinPoint , Object result){
        String methodName = joinPoint.getSignature().getName();

        System.out.println("method " + methodName+" result " + result);
    }

      執行結果如下

result:9
method add result 9
result:4
method div result 4

      使用 Aspectj 註解來實現異常通知

//在方法出現異常時執行,可以訪問到異常對象,且可以指定特定異常在執行通知
    @AfterThrowing(value = "execution(* com.java.spring.aop.impl.*.*(int,int))",throwing = "ex")
    public void afterThrowingLogin(JoinPoint joinPoint , Exception ex){
        String methodName = joinPoint.getSignature().getName();

        System.out.println("method " + methodName+" exception " + ex);
    }

      執行結果如下
在這裏插入圖片描述

      使用 Aspectj 註解來實現環繞通知

/*
    環繞通知需要有 ProceedingJoinPoint 這個參數,這個參數可以決定是否執行目標方法
    環繞通知必須有返回值,返回值爲目標方法返回值
     */

    @Around("execution(* com.java.spring.aop.impl.*.*(int,int))")
    public Object aroundLogin(ProceedingJoinPoint pjd ){

        Object result = null;
        String methodName = pjd.getSignature().getName();

        try {
            //前置通知
            System.out.println("method " + methodName + " begins " + Arrays.asList(pjd.getArgs()));
            //執行目標方法
            result = pjd.proceed();
            //返回通知
            System.out.println("method " + methodName+" result " + result);
        } catch (Throwable e) {
            //異常通知
            System.out.println("method " + methodName+" exception " + e);
        }
        //後置通知
        System.out.println("method " + methodName+" end ");
        return result;
    }

      執行結果如下
在這裏插入圖片描述
      發生異常後如下
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章