1. 程式人生 > >Spring 切面的優先順序&重用切入點(二十三)

Spring 切面的優先順序&重用切入點(二十三)

一、指定切面的優先順序

  • 在同一個連線點上應用不止一個切面時, 除非明確指定, 否則它們的優先順序是不確定的.

  • 切面的優先順序可以通過實現 Ordered 介面或利用 @Order 註解指定.

  • 實現 Ordered 介面, getOrder() 方法的返回值越小, 優先順序越高.

  • 若使用 @Order 註解, 序號出現在註解中.

package aop;

import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Order(1)
@Aspect
@Component
public class VlidationAspect {

	@Before("aop.LoggingAspect.declareJointPointExpression()")
	public void validateArgs(JoinPoint joinPoint){
		System.out.println("-->validate:" + Arrays.asList(joinPoint.getArgs()));
	}
	
}

二、重用切入點

(1)定義 

  • 在編寫 AspectJ 切面時, 可以直接在通知註解中書寫切入點表示式. 同一個切點表示式可能會在多個通知中重複出現;

  • AspectJ 切面中, 可以通過 @Pointcut 註解將一個切入點宣告成簡單的方法. 切入點的方法體通常是空的, 因為將切入點定義與應用程式邏輯混在一起是不合理的.

  • 切入點方法的訪問控制符同時也控制著這個切入點的可見性. 如果切入點要在多個切面中共用, 最好將它們集中在一個公共的類中. 在這種情況下, 它們必須被宣告為 public. 在引入這個切入點時, 必須將類名也包括在內. 如果類沒有與這個切面放在同一個包中
    , 還必須包含包名.

  • 其他通知可以通過方法名稱引入該切入點.

LoggingAspect切面

/**
 * 可以使用 @Order 註解指定切面的優先順序, 值越小優先順序越高
 */
@Aspect
@Component
public class LoggingAspect {

	/**
	 * 定義一個方法, 用於宣告切入點表示式. 一般地, 該方法中再不需要添入其他的程式碼.
	 * 使用 @Pointcut 來宣告切入點表示式.
	 * 後面的其他通知直接使用方法名來引用當前的切入點表示式.
	 */
	@Pointcut("execution(public int aop.ArithmeticCalculator.*(..))")
	public void declareJointPointExpression(){}

	/**
	 * 在 com.atguigu.spring.aop.ArithmeticCalculator 介面的每一個實現類的每一個方法開始之前執行一段程式碼
	 */
	@Before("declareJointPointExpression()")
	public void beforeMethod(JoinPoint joinPoint){
		String methodName = joinPoint.getSignature().getName();
		Object [] args = joinPoint.getArgs();

		System.out.println("The method " + methodName + " begins with " + Arrays.asList(args));
	}

 VlidationAspect切面

package aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Order(1)
@Aspect
@Component
public class VlidationAspect {

    @Before("aop.LoggingAspect.declareJointPointExpression()")
    public void validateArgs(JoinPoint joinPoint){
        System.out.println("-->validate:" + Arrays.asList(joinPoint.getArgs()));
    }
}

結果