1. 程式人生 > >Spring Boot系列04-AOP配置

Spring Boot系列04-AOP配置

閱讀這篇博文時,假定讀者已經掌握了Spring Boot+maven開發應用的入門技巧
初次接觸Spring Boot,那也沒關係,移步Spring Boot + maven 開發的入門教程
10分鐘完成你的第一個Spring Boot應用

1. 使用的核心技術

動態代理

沒有接觸過設計模式的同學,請移步設計模式02-動態代理模式
先了解動態代理設計模式,有助於理解Spring AOP的原理

2. Java Maven專案需要的pom依賴

<dependency>                              
     <groupId
>
org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>

3. 切面Aspect類定義

PointCut(切點)+Advice(通知)

package driver.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import
org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; @Component
@Aspect public class WebControllerAop { //匹配driver.controller包下的所有無參方法 // @Pointcut("execution(* driver.controller..*.*(..))") public void executeService0() { } //匹配driver.controller.WebController類下的所有無參方法 @Pointcut("execution(* driver.controller..WebController.*())") public void executeService() { } /** * 前置通知,方法呼叫前被呼叫 * * @param joinPoint */ @Before("executeService()") public void doBeforeAdvice(JoinPoint joinPoint) { System.out.println("Before通知"); } // 方法體執行後,在方法return返回值前執行 @After("executeService()") public void doAfterAdvice(JoinPoint joinPoint) { System.out.println("After通知"); } // 方法return返回值之後執行,需要對方法返回值做加工的可以用此通知 @AfterReturning(value="executeService()",returning="keys") public void doAfterReturningAdvice1(JoinPoint joinPoint,Object keys){ System.out.println("AfterReturning通知"); } //環繞通知,方法執行前後都可以增加處理邏輯, //值得注意的是,環繞通知方法的切點必須用ProceedingJoinPoint @Around("executeService()") public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint) { System.out.println("環繞通知執行方法前"); try {// obj之前可以寫目標方法執行前的邏輯 Object obj = proceedingJoinPoint.proceed();// 呼叫執行目標方法 System.out.println("環繞通知執行方法後"); return obj; } catch (Throwable throwable) { throwable.printStackTrace(); } return null; } }

4. 測試用的目標類定義

1. driver.controller.WebController

package driver.controller;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import driver.config.ConfigHelper;
import driver.service.BootService;

@Controller
public class WebController {
    @RequestMapping(value="/ttt",method=RequestMethod.GET)
    @ResponseBody
    public String ttt(){
        return "ttt";
    }
}
  1. 瀏覽器會返回 ttt字串
  2. 會輸出如下日誌
    這裡寫圖片描述

2. driver.controller.InterfaceController

package driver.controller;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class InterfaceController {
/**
     * @PathVariable
     */
    @RequestMapping("/path/{name}/{age}")
    @ResponseBody
    public String getNames(@PathVariable("name")String a,@PathVariable("age")int age) {
        //System.out.println("名字是:"+a+",年齡:"+age);
        return "name:"+a+",age:"+age;
    }
}

執行結果:
1. 瀏覽器返回字串: name:xiaoming,age:20
但是不會有上述截圖的AOP相關日誌

總結

使用Spring Boot開發應用時,通過Spring提供的AOP能力,
在執行跟切點匹配的方法時,能把通用的前置、後置處理跟具體的業務邏輯實現分離、解耦

舉兩個特別常用且有效的應用場景:
1. 方法執行前後記日誌
2. 事務控制

本篇博文旨在引導讀者基於Spring Boot使用AOP功能,
具體的知識點,如PointCut/Advice定義等,用到時自行查閱資料。