常用於 authentication(使用服務前驗證身分)、record log(紀錄行為日誌)
=> 屬橫切面,與系統主要服務功能較無直接關係
基本介紹
基於OOP:把橫切面邏輯封裝
類似 Proxy Pattern
集中處理非核心邏輯之需求
一段話了解AOP
抽離非核心之共用邏輯,於特定時機點(程式前/後),執行其他次要業務邏輯的程式,使核心邏輯不受切面邏輯影響
為什麼使用AOP
OOP是以侵入性方式對原程式碼加入額外程式 => 重複、關注點混淆且難以維護
AOP可降低系統的耦合,增加程式的可擴充性
專注職責,降低依賴
術語
- Aspect
A modularization of a concern that cuts across multiple classes. (打包好的模組)
- Point Cut
A predicate that matches join points. (切入點的定義
)
- Join Point
A point during the execution of a program. (aspect 呼叫的時機點)
- Advice
Action taken by an aspect at a particular join point. (aspect 的實作)
- Weaving
Linking aspects with other application types or objects to create an advised object. (advice被應用至物件上之過程)
Diagram

Code Snippet
Ex1. OOP Method
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class SettingService { public Object saveSetting(String name) { try { saveNameToDb(name); recordLog(Level.INFO, "hello success."); return ResponseEntity.ok(); } catch(Exception e) { recordLog(Level.INFO, "hello fail."); return ResponseEntity.badRequest(); } } }
|
Ex2. AOP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
public class SettingService { @LogRecord(logInfo = "'Save' + #name ", level = "INFO") public Object saveSetting(String name) { try { saveNameToDb(name); return ResponseEntity.ok(); } catch(Exception e) { return ResponseEntity.badRequest(); } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| @Aspect @Component public class LogAOP {
@Pointcut(value=“@annotation(logRecord)") public void pointcut() {};
@Before(value = "pointcut()") public void getLogInfoBefore(JoinPoint joinPoint) {
@AfterReturning(value = "pointcut()", returning = "returnValue") public void getLogInfoAfterReturning(JoinPoint joinPoint, Object returnValue) {
@After(value = "pointcut()") public void getLogInfoAfter(JoinPoint joinPoint) {
@Around(value = "pointcut()") public Object getLogInfoAround(ProceedingJoinPoint pjp) {
@AfterThrowing(value = "pointcut()“, throwing= “e" ) public void getLogInfoAfterThrowing(Exception e) {
}
|
1 2 3 4 5 6 7 8 9
| @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) public @interface LogRecord{ String title(); String logInfo();
}
|