1. 程式人生 > >Spring註解開發8 --- AOP註解

Spring註解開發8 --- AOP註解

AOP方法上的註解有:

@Before():這個是前置呼叫,在方法之前掉呼叫

@After() 這個稱為後置呼叫,不管方法執行是正常還是異常都會呼叫

@Around() 這個表示的是環繞 在呼叫方法之前和之後呼叫 一般用來記錄日誌,需要joinPoint.proceed()推動目標進行

@AfterReturning()這個表示的是正常執行後,返回資料的時候呼叫

@AfterThrowing()這個表示的是丟擲異常的時候呼叫

@Aspect:告訴容器這是一個切面類

@Pointcut() :切入點表示式的位置

@EableAspectjAutoProxy:開啟基於註解的aop模式,原來是在xml中配置

例子:

1.需要匯入包

 <dependency>
      <groupId>org.springframework</groupId>
       <artifactId>spring-aspects</artifactId>
      <version>5.0.8.RELEASE</version>
</dependency>

2.業務類

public class Caculator {

    public Integer cal(int a,int b) {
        System.out.println("Caculator ..cal");
        return  a/b;
    }
}

3.切面類

@Aspect
public class LogsAspects {

    @Pointcut("execution( * com.wusu.aop.Caculator.*(..))")
    public void pointcut(){};

    @Before("pointcut()")
    public void logStart(JoinPoint joinPoint){
        System.out.println("開始計算"+joinPoint.getSignature().getName()+": 引數是:"+ Arrays.asList(joinPoint.getArgs()).toString());
    }
    @After("pointcut()")
    public void logEnd(JoinPoint joinPoint){
        System.out.println("結束計算"+joinPoint.getSignature().getName());
    }
    //這個JoinPoint必須放在第一個才能使用
    @AfterReturning(value = "pointcut()",returning = "result")
    public void logReturn(JoinPoint joinPoint,Object result){
        System.out.println("開始返回"+joinPoint.getSignature().getName()+",return :"+ result);
    }
    @Around("pointcut()")  //這個必須要有返回值值,否則正常的有返回值的沒有結果
    public Object logRound(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("環繞執行前。。。引數是:"+joinPoint.getArgs());
        Object object = joinPoint.proceed(joinPoint.getArgs());
        System.out.println("環繞執行後。。。引數是:"+joinPoint.getArgs());
        return object;
    }
    @AfterThrowing(value = "pointcut()",throwing = "exception")
    public void logThrowing(Exception exception){
        System.out.println("丟擲異常"+exception);
    }
}

對於@PointCut裡面的表示式解釋:

定義切入點表示式

 1>:定義一個沒有實現的方法

2>:在這個方法上 使用切入點表示式的註解Pointcut

execution ()你記成語法規則

 第一個 * 代表的是返回注入方法的返回資料的型別

第二個 * 代表的是UserDAO這個類裡面的所有方法

“..” 代表的是注入方法裡面的引數型別 這裡因為可以是任意型別 所以使用 “..” ,這裡是兩個點

4. 配置類,業務類和切面類都需要放入IOC容器中

         需要使用@EnableAspectJAutoProxy開啟自動代理

@EnableAspectJAutoProxy
@Configuration
public class MainConfig {
    @Bean
    public Caculator caculator(){
        return  new Caculator();
    }
    @Bean
    public LogsAspects logsAspects(){
        return new LogsAspects();
    }
}

5.測試類,需要從IOC容器中獲取這個業務類才是被代理後的類

public class TestAop {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        Caculator caculator = applicationContext.getBean(Caculator.class);
        int cal = caculator.cal(16, 0);

    }
}

結果顯示:

開始計算cal: 引數是:[16, 0] Caculator ..cal 結束計算cal 丟擲異常java.lang.ArithmeticException: / by zero