You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring如何向自定义注解传递方法命名参数及自定义权限参数?

需求可实现,具体实现方案如下

Java注解本身不支持直接引用方法参数作为属性值(注解属性只能是编译期常量),我们可以通过「注解传参数名+切面动态解析参数值」的方式达成目标,该方案可通用到所有自定义注解的参数传递场景。

1. 先定义权限枚举(可选,也可直接用字符串)

public enum PermissionType {
    READ, WRITE
}

2. 调整自定义注解定义

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthorizeUser {
    // 要获取的方法参数名列表
    String[] paramNames() default {};
    // 权限类型
    PermissionType permission();
}

3. 完善切面逻辑

核心逻辑是通过方法签名获取参数名和参数值的映射关系,再根据注解中配置的参数名提取对应的值:

@Aspect
@Component
public class AuthorizeUserAspect {
    @Autowired
    PermissionService permissionService;
    // Spring自带的参数名解析器
    private final ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();

    @Around("@annotation(authorizeUser)")
    public Object authorize(ProceedingJoinPoint joinPoint, AuthorizeUser authorizeUser) throws Throwable {
        // 1. 获取当前拦截的方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        // 2. 获取方法的参数名数组、参数值数组
        String[] paramNames = parameterNameDiscoverer.getParameterNames(method);
        Object[] paramValues = joinPoint.getArgs();
        // 3. 构建参数名-参数值映射
        Map<String, Object> paramMap = new HashMap<>();
        if (paramNames != null) {
            for (int i = 0; i < paramNames.length; i++) {
                paramMap.put(paramNames[i], paramValues[i]);
            }
        }
        // 4. 从注解中获取配置的参数名,提取对应的值
        String[] requiredParamNames = authorizeUser.paramNames();
        Object jwtAuthUser = paramMap.get(requiredParamNames[0]);
        Object businessId = paramMap.get(requiredParamNames[1]);
        // 5. 获取权限参数
        PermissionType permission = authorizeUser.permission();
        
        // 此处填写自定义权限校验逻辑
        // permissionService.check(jwtAuthUser, businessId, permission);
        
        return joinPoint.proceed();
    }
}

4. Controller层使用示例

@AuthorizeUser(paramNames = {"jwtAuthUser", "businessId"}, permission = PermissionType.READ)
@GetMapping("/businesses/{businessId}/test")
public ResponseEntity<List<BusinessDto>> getBusinessListAsClient(Principal jwtAuthUser, @PathVariable String businessId) throws Exception {
    // 业务逻辑
}

方案说明

这套实现完全脱离参数位置限制,只要注解中填写的参数名和方法签名的参数名一致就能正确取值,逻辑可直接复用到其他自定义注解场景,不需要修改核心解析代码。


内容的提问来源于stack exchange,提问作者Mankind1023

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 22:54:03