Spring Boot 面向切面編程

目錄

  • 前言
  • 編程範式主要有以下幾類
  • aop註解
  • 用法

前言

spring提供兩個核心功能,一個是Ioc(控制反轉),另一個是Aop(面向切面編程),Ioc有助於應用對象之間的解耦,AOP則可以實現橫切關注點(如日誌、安全、緩存、重複提交和事務管理)與他們所影響的對象之間的解耦。

編程範式主要有以下幾類

  • AOP(Aspect Oriented Programming)面向切面編程
  • OOP(Object Oriented Programming)面向對象編程
  • POP(procedure oriented programming)面向過程編程
  • FP(Functional Programming)面向函數編程

aop註解

AOP主要包含了通知、切點和連接點燈術語,介紹如下:

  • 通知(Advice)

通知定義了切面是什麼以及何時被調用,何時調用包含以下幾種:

  1. Before 在方法被調用之前調用通知
  2. After 在方法完成之後調用通知,無論方法執行是否成功
  3. After-returning 在方法成功執行之後調用通知
  4. After-throwing 在方法拋出異常後調用通知
  5. Around 通知包裹了被通知的方法,在被通知的方法調用之前和調用之後執行自定義的行爲
  • 切點(PointCut)

通知定義了切面是什麼和何時被調用,切點定義了何處被調用,切點的定義會匹配通知所要織入的一個或多個連接點,我們通常使用明確的類的方法名稱來指定這些切點,或是利用正則表達式定義匹配的類和方法名稱來指定這些切點。

  • 連接點(JoinPoint)

連接點是在應用執行過程中能夠插入切面的一個點,這個點可以是調用方法時,拋出異常時,甚至是修改一個字段時,切面代碼可以利用這些連接點插入到應用的正常流程中,並添加新的行爲,如日誌、安全、事務、緩存等。

  • @Aspect: 切面,由通知和切入點共同組成,這個註解標註在類上表示爲一個切面。
  • @Joinpoint: 連接點,被AOP攔截的類或者方法,在前置通知中有介紹使用@Joinpoint獲取類名、方法、請求參數。
  • Advice: 通知的幾種類型
  • @Before: 前置通知,在某切入點@Pointcut之前的通知
  • @After: 後置通知,在某切入點@Pointcut之後的通知無論成功或者異常。
  • @AfterReturning: 返回後通知,方法執行return之後,可以對返回的數據做加工處理。
  • @Around: 環繞通知,在方法的調用前、後執行。
  • @AfterThrowing: 拋出異常通知,程序出錯跑出異常會執行該通知方法。
  • @Pointcut: 切入點,從哪裏開始。例如從某個包開始或者某個包下的某個類等。

用法

AOP在spring中有兩種配置方式,一是xml配置的方式,二是自動註解的模式。

自動註解AOP
聲明切面類,包含註解@Aspect以及何時執行通知(Advice)
package com.ganji.demo.service.aspect;

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

/**
 * Created by admin on 2015/9/2.
 */
@Aspect
@Service
public class XmlAopDemoUserLog {

// 配置切點 及要傳的參數   
    @Pointcut("execution(* com.ganji.demo.service.user.UserService.GetDemoUser(..)) && args(id)")
    public void pointCut(int id)
    {

    }

// 配置連接點 方法開始執行時通知
    @Before("pointCut(id)")
    public void beforeLog(int id) {
        System.out.println("開始執行前置通知  日誌記錄:"+id);
    }
//    方法執行完後通知
    @After("pointCut(id)")
    public void afterLog(int id) {
        System.out.println("開始執行後置通知 日誌記錄:"+id);
    }
//    執行成功後通知
    @AfterReturning("pointCut(id)")
    public void afterReturningLog(int id) {
        System.out.println("方法成功執行後通知 日誌記錄:"+id);
    }
//    拋出異常後通知
    @AfterThrowing("pointCut(id)")
    public void afterThrowingLog(int id) {
        System.out.println("方法拋出異常後執行通知 日誌記錄"+id);
    }

//    環繞通知
    @Around("pointCut(id)")
    public Object aroundLog(ProceedingJoinPoint joinpoint,int id) {
        Object result = null;
        try {
            System.out.println("環繞通知開始 日誌記錄"+id);
            long start = System.currentTimeMillis();

            //有返回參數 則需返回值
            result =  joinpoint.proceed();

            long end = System.currentTimeMillis();
            System.out.println("總共執行時長" + (end - start) + " 毫秒");
            System.out.println("環繞通知結束 日誌記錄");
        } catch (Throwable t) {
            System.out.println("出現錯誤");
        }
        return result;
    }
}

以上即實現aop。

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