首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Spring AOP 實戰:基於註解的權限驗證切面實現

     編輯:Java 綜合教學

依賴引入

<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjrt</artifactId>
  <version>1.9.21</version>
</dependency>
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>1.9.21</version>
</dependency>

切面類實現

@Aspect
@Component
public class LoginCheckAspect {

    // 環繞通知:攔截所有 @RequestMapping 註解的方法
    @Around("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
    public Object checkUser(ProceedingJoinPoint pjp) throws Throwable {
        // 1. 獲取方法參數(如 HttpServletRequest)
        Object[] args = pjp.getArgs();
        HttpServletRequest request = Arrays.stream(args)
            .filter(HttpServletRequest.class::isInstance)
            .map(HttpServletRequest.class::cast)
            .findFirst().orElse(null);

        // 2. 驗證登入狀態(示例:Session 中是否有 user 屬性)
        if (request != null && request.getSession().getAttribute("user") == null) {
            throw new RuntimeException("未登入,請先登入!");
        }

        // 3. 前置日誌
        System.out.println("【AOP】進入方法:" + pjp.getSignature().getName());

        // 4. 執行目標方法
        Object result = pjp.proceed();

        // 5. 後置日誌
        System.out.println("【AOP】方法執行完成");
        return result;
    }

    // 前置通知:Controller 層所有方法
    @Before("execution(* com.homework.controller..*.*(..))")
    public void logBefore() {
        System.out.println("【AOP】Controller 方法即將執行");
    }
}

關鍵點解析

  • @Around 需手動呼叫 pjp.proceed() 繼續執行,可完整控制前後邏輯、異常捕獲、返回值修改。
  • @Before 僅執行前置邏輯,無法阻斷流程。
  • 切點表達式:@annotation(...) 針對註解;execution(...) 針對包/類/方法簽名。
  • 註入 HttpServletRequest 時需從 JoinPoint.getArgs() 手動篩選,因 AOP 代理非 Controller 直接註入。

進階:自定義權限註解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequirePermission {
    String value(); // 權限標識,如 "user:delete"
}

@Around("@annotation(requirePermission)")
public Object checkPermission(ProceedingJoinPoint pjp, RequirePermission requirePermission) {
    String perm = requirePermission.value();
    // 從 SecurityContext / JWT / Session 獲取當前用戶權限集合
    if (!currentUserHasPermission(perm)) throw new AccessDeniedException("權限不足:" + perm);
    return pjp.proceed();
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved