SpringMVC 基于方法参数解析器自定义注入参数方案

本文介绍了如何在SpringMVC中通过自定义注解和方法参数解析器实现User信息和Token的自动注入,免去业务开发人员手动获取这些公共信息的步骤。首先声明自定义注解@User和@Token,然后创建User信息类。接着在拦截器中获取请求头中的Token并设置到请求属性中。接下来定义一个方法参数解析器UserAndTokenMethodArgumentResolver来解析带有@User或@Token注解的参数。最后,注册拦截器和参数解析器,并在Controller中使用注解直接获取User信息和Token。通过这种方式,可以简化代码并提高代码复用性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、SpringMVC 基于方法参数解析器自定义注入参数

SpringMVC Web 项目开发中,我们可能需要经常获取一些公共的信息,比如用户信息、请求的 Token 等等,这种情况下我们可以封装一个工具类进行统一获取,也可以通过本篇文章讲解的方法参数解析器进行自动注入。

例如:这里以User 信息和Token为例 ,我们可以以下面这种方式注入到 Controller 层,其中业务开发人员无需关注数据从何而来,直接开箱使用即可:

在这里插入图片描述

下面看下实践的过程:

1. 声明自定义注解

注解中也可以加上一些参数进行更灵活的注入信息。

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface Token {
}
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface User {
}

2. 声明 User 信息类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserInfo {
    private Long id;
    private String userName;
    // 省略其他字段
}

3. 在拦截器中获取相关信息

@Component
@Slf4j
public class UserInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("token");
        response.setContentType("text/json;charset=utf-8");
        request.setAttribute("CURRENT_USER_INFO", getUserInfo(token));
        request.setAttribute("TOKEN",token);
        return true;
    }

    /**
     * 获取用户信息
     * @param token token
     * @return 用户信息
     */
    private UserInfo getUserInfo(String token){
        // 查询用户逻辑.....
        // 具体逻辑省略
        // 这里仅演示方法参数解析器效果,先以固定值返回。
        return new UserInfo(1L,"张三");
    }
}

4. 方法参数解析器注入参数

@Component
public class UserAndTokenMethodArgumentResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        // 如果参数类型是UserInfo并且有User注解,或者有Token注解则支持
        if ((parameter.getParameterType().isAssignableFrom(UserInfo.class) && parameter.hasParameterAnnotation(User.class))
                || parameter.hasParameterAnnotation(Token.class)) {
            return true;
        }
        return false;
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        if (parameter.getParameterType().isAssignableFrom(UserInfo.class) && parameter.hasParameterAnnotation(User.class)) {
            return webRequest.getAttribute("CURRENT_USER_INFO",
                    RequestAttributes.SCOPE_REQUEST);
        } else if (parameter.hasParameterAnnotation(Token.class)) {
            return webRequest.getAttribute("TOKEN",
                    RequestAttributes.SCOPE_REQUEST);
        }
        return null;
    }
}

5. 注册拦截器和参数解析器

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Resource
    UserInterceptor userInterceptor;

    @Resource
    UserAndTokenMethodArgumentResolver userAndTokenMethodArgumentResolver;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(userInterceptor).addPathPatterns("/**");
    }

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(userAndTokenMethodArgumentResolver);
    }
}

6. 使用

@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {

    @GetMapping("/test")
    public void test(@User UserInfo user, @Token String token) {
        log.info("用户信息:{}",user.toString());
        log.info("Token: {}", token);
    }
}

访问测试接口:

在这里插入图片描述

查看日志打印情况:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小毕超

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值