SpringBoot 簡單整合AOP

開發環境爲 IDEA,jdk1.8,Maven,SpringBoot2.1.3

AOP使用場景很多,此示例場景爲對 web 請求進行日誌記錄

一、在pom文件中導入AOP依賴

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

二、定義切面類,實現所需功能.根據需求,切面類可定義多個,且可以自定義切面類的執行順序.

/**
 * 簡單的aop日誌配置
 *
 * @author YoonaLt
 * @date 2019/10/29
 */
@Aspect  // 標記此類爲切面類
@Component
@Slf4j
@Order(value = 2)  // 切面類執行順序權重
public class LogAspect {

    /**
     * 定義切入點,可以定義多個。@After(),@Before()等只需填寫方法名"pointCut()","pointCut1()","pointCut2()"即可.
     * <p>
     * execution()的一些含義例如:
     * execution(public * com.yoona.aop.*.*(..)),"com.yoona.aop"包下不限返回值的公共方法執行
     * execution(* my*(..)),任何一個以"my"開頭的方法執行
     * execution(* com.yoona.aop.AopController.*(..)),AopController接口下任意方法執行
     * 在多個表達式之間使用 ||,or表示"或",使用 &&,and表示"與",!表示"非".例如:execution()||execution()
     * <p>
     * 還有一些其他表達式,如within(),this(),target(),args(),bean()等,與execution()使用略有差異,這裏就不一一介紹了.
     * 需要注意的是,當表達式書寫錯誤時,會拋出異常:warning no match for this type name:com.xx.xx [Xlint:invalidAbsoluteTypeName]
     */
    @Pointcut("execution(* com.yoona.aop.AopController.*(..))")
    public void pointCut() {
    }

    /**
     * 也可以直接定義切入點,@Before("execution(public * com.yoona.*.*(..))"),這樣就不必定義切入點 @Pointcut 了.
     *
     * @param joinPoint 連接點,可以獲取切入點方法的一些信息
     */
    @Before("pointCut()")
    public void atBefore(JoinPoint joinPoint) {
        log.debug(" @Before 在方法執行前執行");
        log.debug("切入點的方法名爲 " + joinPoint.getSignature().getName());
    }

    /**
     * 方法結束後執行,無論是正常結束還是拋出異常都會執行.
     */
    @After("pointCut()")
    public void atAfter() {
        log.debug(" @After 方法執行......");
    }

    /**
     * 方法正常返回後執行
     *
     * @param o 方法返回的值
     */
    @AfterReturning(pointcut = "pointCut()", returning = "o")
    public void atAfterReturning(Object o) {
        log.debug(" @AfterReturning 方法執行......");
        log.debug("方法的返回值爲" + o.toString());
    }

    /**
     * 方法拋出異常時執行
     *
     * @param t 方法拋出的異常
     */
    @AfterThrowing(pointcut = "pointCut()", throwing = "t")
    public void atAfterThrowing(Throwable t) {
        log.debug(" @AfterThrowing 方法拋出異常時執行......");
        log.debug("方法拋出的異常爲" + t.toString());
    }
}

 

/**
 * @author YoonaLt
 * @date 2019/10/29
 * 再定義一個執行其他功能的切面類
 */
@Aspect
@Component
@Slf4j
@Order(value = 1)
public class OtherAspect {

    /**
     * 其他功能切面類
     */
    @Before("execution(* com.yoona.aop.AopController.*(..))")
    public void atBefore() {
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest httpServletRequest = sra.getRequest();
        String method = httpServletRequest.getMethod();
        log.debug("其他功能切面類執行了" + "\nMethod:" + method + "\nCache-Control:" + httpServletRequest.getHeader("Cache-Control"));

    }
}

三、測試接口

/**
 * aop測試接口
 *
 * @author YoonaLt
 * @date 2019/10/29
 */
@Slf4j
@RestController
@RequestMapping(value = "aop")
public class AopController {

    @GetMapping(value = "test")
    public Integer aopTest() {
        log.debug("測試方法執行了");
        // 使方法拋出異常
        int i = 10 / 0;
        return 10;
    }
}

四、Run:

訪問接口

 

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