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

Spring AOP 註解驅動權限驗證:從原理到落地的完整方案

     編輯:Java 相關知識

痛點與解決方案

傳統權限檢查硬編碼在 Action/Service 方法中,導致:代碼重複、業務邏輯混雜、角色變更需全量改代碼。本文採用 Spring AOP + 自定義註解 + Struts2 全局異常映射 實現聲明式權限控制:開發者僅需在方法上標註 @UserAccessAnnotation(isLogin=YES),框架自動攔截驗證,無權限則拋出異常跳轉登錄頁。

核心組件設計

1. 權限註解定義

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface UserAccessAnnotation {
    ISLOGIN isLogin();  // 枚舉:YES/LOGOUT/NO
}

2. 切點集中管理

@Aspect
public class SystemArchitecture {
    @Pointcut("@annotation(com.example.annotation.UserAccessAnnotation)")
    public void userAccess() {}
}

3. 切面實現與 SpEL 參數綁定

@Aspect
public class PermissionAspect extends BaseAction {
    @Before(value="com.example.aspect.SystemArchitecture.userAccess() && @annotation(userAccessAnnotation)",
            argNames="userAccessAnnotation")
    public void checkPermission(UserAccessAnnotation userAccessAnnotation) {
        ISLOGIN required = userAccessAnnotation.isLogin();
        if (!authService.userLogin(getCurrentUser()).equals(required.toString())) {
            throw new NoPermissionException(getText("user_no_permission_error"));
        }
    }
}

argNames 將註解實例綁定為切面方法參數,實現動態權限判斷。

4. Spring AOP 啟用與 Bean 配置

<aop:aspectj-autoproxy/>
<bean id="permission" class="com.example.aspect.PermissionAspect" scope="prototype">
    <property name="authService" ref="AuthService"/>
</bean>

5. Struts2 全局異常處理

<global-exception-mappings>
    <exception-mapping exception="com.example.exceptions.NoPermissionException" result="loginerror"/>
</global-exception-mappings>
<global-results>
    <result name="loginerror">/WEB-INF/jsp/login.jsp</result>
</global-results>

進階靈活性說明

  • 註解位置不限:可標註在 Action、Service、Controller 任意層
  • 異常處理可插拔:拋出異常、返回 JSON、重定向 URL 由切面實現邏輯決定
  • 擴展角色權限:註解增加 roles()、permissions() 數組屬性,切面中委託 AuthService 完成 RBAC 校驗

AOP 代理邊界提醒

Spring AOP 基於 JDK 動態代理/CGLIB,**僅攔截 public 方法的外部調用**;同類內部調用、非 public 方法、final 方法均失效。解決方案:AopContext.currentProxy() 獲取代理引用,或改用 AspectJ LTW(Load-Time Weaving)。

總結

該方案以 「註解聲明 + AOP 攔截 + 異常統一處理」 三層結構,實現權限邏輯與業務代碼零耦合,單人維護註解與切面即可管控全站權限,顯著降低開發成本與維護複雜度。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved