🔥
Caster 開發日誌
  • Java
    • JVM Performance Tool
      • Java Debug Wire Protocol (JDWP) 的詳細介紹
      • JConsole 詳細介紹
    • Spring Boot
      • Spring Security
      • Spring Boot Admin
      • Spring Event
      • Spring AOP
      • Spring Boot JUnit 5
      • Apache Dubbo
    • Reflect 應用
    • ELK + F 建構
    • Socket.IO
    • OCR - 光學字元辨識
    • 讀取JAR resource文件
    • LocalTime & MySQL時間精度
    • Gradle multi module
    • MyBatis-Plus
    • Java Date operation
    • Java IP to Long
    • Apache Commons lang3 應用
      • Function 應用
    • Cloud Platform
      • Amazon S3
        • SDK V1
          • Bucket
        • SDK V2
          • Bucket
      • Google Cloud Platform
      • Azure Cloud
        • Storage
      • OVHcloud
        • Config
    • SSL/TLS工具
    • Util 工具
      • Jackson Json工具
      • Charles應用
      • JMeter – Performing Distributed Load Testing with Docker
    • Redis
      • Stream
      • Redisson 分布式鎖機制
      • Create Redis Cluster Using Docker
      • List Operations
    • Java 8
      • method & constructor Reference
      • CompletableFuture
      • FunctionInterface
      • Stream 應用
      • 繁簡轉換 - 簡易調整
    • MySQL
      • 建立測試用 流水號Table
      • SQL 效能調校 - Explain
      • SQL 效能調校 - Partition
      • 排程 - Event
    • Apache ShardingSphere
  • Kubernetes
    • 初入江湖(K8S)
    • 零中斷服務滾動更新
    • Kubernetes DNS
    • Ingress & Ingress Controller 教學
    • Ingress TLS Easy setup
  • 指令集
  • Telegram
  • SourceTree
    • 踩坑紀錄(ㄧ) - Git Flow
    • 踩坑紀錄(二) - 修改檔名
  • 專案統計
    • Robot
    • Recharge
  • GitHub
    • Actions
  • GitLab
    • 介紹 GitLab
    • 使用 Docker 自架 GitLab
    • 簡介 GitLab CI/CD
      • GitLab Runner 詳細介紹與設定方式
Powered by GitBook
On this page
  • 技術詳解參考
  • 實作測試 - 效能統計(Method執行時間)
  • annotation方式:
  • 實作測試 - 日誌紀錄
  • 結語
  1. Java
  2. Spring Boot

Spring AOP

PreviousSpring EventNextSpring Boot JUnit 5

Last updated 1 year ago

Aspect Oriented Programming(AOP):意為:面向切面編程。從本質上講,它是一種無需修改代碼即可向現有代碼添加行為的方法。通過預編譯方式和運行期間動態代理實現程序功能的統一維護的一種技術。是Spring框架中的一個重要內容,利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程式的可重用性,同時提高了開發的效率。

主要功能 日誌記錄、性能統計、安全控制、事務處理、異常處理等等。 我們知道AOP是通過動態代理實現的,而Spring的AOP是實現有兩種,一個是JDK動態代理,一個是CGLIB實現。

技術詳解參考

實作測試 - 效能統計(Method執行時間)

annotation方式:

定義一個annotation介面

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecutionTime {
}

aspect class

@Aspect
@Component
public class LogExecutionTimeAop {
	Logger log = LoggerFactory.getLogger("aopTest");

	@Pointcut("@annotation(com.ecommerce.mini.anno.LogExecutionTime)")
	public void logExecution() {
	}

	@Around("logExecution()")
	public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
		log.debug("---> around");
		long start = System.currentTimeMillis();

		Object obj = joinPoint.proceed();

		long executionTime = System.currentTimeMillis() - start;
		log.debug("---> around " + joinPoint.getSignature() + " executed in " + executionTime + "ms");
		return obj;
	}

	@After("logExecution()")
	public void after(JoinPoint joinPoint) {
		log.debug("---> after");
	}

	@AfterReturning(value = "logExecution()", returning = "returnObject")
	public void afterReturning(JoinPoint joinPoint, Object returnObject) {
		log.debug("---> AfterReturning");
	}

	@Before("logExecution()")
	public void before(JoinPoint joinPoint) {
		log.debug("---> before");
	}
}

Controller

@RestController
@RequestMapping("/common")
public class CommonController {
	Logger log = LoggerFactory.getLogger("aopTest");

	@GetMapping("/test")
	@LogExecutionTime
	public ResponseEntity test() {
		log.debug("do something.....");
		return ResponseEntity.ok();
	}
}

output

aopTest - ---> around
aopTest - ---> before
aopTest - do something.....
aopTest - ---> AfterReturning
aopTest - ---> after
aopTest - ---> around ResponseEntity com.ecommerce.mini.controller.CommonController.test(String) executed in 6ms

execution方式:

aspect class 增加

@Pointcut("execution(* com.ecommerce.mini.controller.*Controller.*(..))")
public void pointcut() {
}

output

aopTest - ---> around
aopTest - ---> before
aopTest - do something.....
aopTest - ---> AfterReturning
aopTest - ---> after
aopTest - ---> around ResponseEntity com.ecommerce.mini.controller.CommonController.test(String) executed in 6ms

實作測試 - 日誌紀錄

實際應用場景會出現在記錄後台使用者CRUD記錄,當問題出現時可以根據當時User傳送的資料來當偵錯測試的依據。Server Reponse 有一定規範,操作上會更有架構性。

aspect class

@AfterReturning(value = "pointcut()", returning = "returnObject")
public void afterReturning(JoinPoint joinPoint, Object returnObject) {
	log.debug("---> AfterReturning");
	try {
		ResponseEntity a = (ResponseEntity) returnObject;
		JSONResult b = (JSONResult) a.getBody();
		if (b.getUserActionLog() != null) {
			log.debug("afterReturning -> todo: insert user action log.");
		} else {
			log.debug("afterReturning -> not found user action log obj.");
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
}

Controller

@GetMapping("/test")
@LogExecutionTime
public ResponseEntity test() {
	log.debug("do something.....");
	UserActionLog actionLog = new UserActionLog();
	actionLog.setNewInfo("do something..... bla bla bla");
	return ResponseEntity.ok(JSONResult.createResult(SuccessCodeMsg.COMMON_OK).addUserActionLog(actionLog));
}

output

aopTest - ---> around
aopTest - ---> before
aopTest - do something.....
aopTest - ---> AfterReturning
aopTest - afterReturning -> todo: insert user action log.
aopTest - ---> after
aopTest - ---> around ResponseEntity com.ecommerce.mini.controller.CommonController.test() executed in 12ms

結語

在實際使用場景上,還是有許多需要考慮的地方,比如在比對前後異動資訊時,需要不去影響核心邏輯部分資料,在切分工作時要再更細心一點。

https://www.baeldung.com/spring-aop
https://bingdoal.github.io/backend/2020/11/aop-and-point-cut-in-spring-boot/
https://blog.csdn.net/qq_36551991/article/details/106740138
這是我實際透過AOP 紀錄 user action log