可以扩展 Spring MVC,自定义参数解析器,解析所需要的参数,这里模拟一个自定义注解,获取当前登录用户的逻辑

自定义注解

定义了一个自定义注解 @LoginUser 用于获取当前登录用户

  1. @Target({ElementType.PARAMETER})
  2. @Retention(RetentionPolicy.RUNTIME)
  3. public @interface LoginUser {
  4. }

自定义参数解析器

自定义一个参数解析器,用于解析 @LoginUser 的注解,并赋值

  1. @Component
  2. public class LoginUserResolver implements HandlerMethodArgumentResolver {
  3. @Override
  4. public boolean supportsParameter(MethodParameter parameter) {
  5. return parameter.hasParameterAnnotation(LoginUser.class);
  6. }
  7. @Override
  8. public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
  9. // 从 request 或 redis 中获取用户逻辑...
  10. System.out.println("---从 request 或 redis 中获取用户逻辑---");
  11. Map<String, Object> map = new HashMap<>();
  12. map.put("sessionId", webRequest.getSessionId());
  13. map.put("id", "123456");
  14. map.put("name", "eric");
  15. return map;
  16. }
  17. }

添加参数解析器

将自定义的参数解析器添加到 argumentResolvers 列表中,我们可以通过重写 addArgumentResolvers 方法来实现

注意:

如果自定义的参数是一个 Map,List 这样的对象,很可能就会被 Spring 自带的参数解析器所解析,这样就不会使用到我们自定义的参数解析器了,所以我们要想办法,让我们的参数解析器优先级高于 Spring 自带的一系列参数解析器

  1. @Configuration
  2. @ComponentScan("org.wesoft.mvc")
  3. @EnableWebMvc // 相当于 XML 中的 <mvc:annotation-driven/>
  4. public class AppConfig implements WebMvcConfigurer {
  5. /**
  6. * 添加参数解析器
  7. *
  8. * @param resolvers initially an empty list
  9. */
  10. @Override
  11. public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
  12. // 这里其实是传过来一个空集合,对应着 customArgumentResolvers
  13. // 也就是我们其实是在 customArgumentResolvers 里添加自定义方法
  14. // 然后 spring mvc 会将这个集合合并到 argumentResolvers 中,所以并不能保证执行顺序
  15. resolvers.add(new LoginUserResolver());
  16. }
  17. // 会在 Spring mvc 环境初始化完成之后,加载这个方法
  18. @Autowired
  19. public void iniArgumentsResolvers(RequestMappingHandlerAdapter requestMappingHandlerAdapter) {
  20. List<HandlerMethodArgumentResolver> argumentResolvers = new ArrayList<>(requestMappingHandlerAdapter.getArgumentResolvers());
  21. // 获取自定义的参数解析器
  22. List<HandlerMethodArgumentResolver> customArgumentResolvers = requestMappingHandlerAdapter.getCustomArgumentResolvers();
  23. // 删除原来集合中的自定义参数解析器
  24. argumentResolvers.removeAll(customArgumentResolvers);
  25. // 重新加入到最前面
  26. argumentResolvers.addAll(0, customArgumentResolvers);
  27. // 重新设置参数解析器
  28. requestMappingHandlerAdapter.setArgumentResolvers(argumentResolvers);
  29. }
  30. }

使用自定义注解获取当前登录用户

  1. @RequestMapping("/test.do")
  2. @ResponseBody
  3. public Object test(@LoginUser Map loginUser) {
  4. System.out.println("loginUser = " + loginUser);
  5. Map<String, Object> map = new HashMap<>();
  6. map.put("name", name);
  7. map.put("userEntity", userEntity);
  8. return map;
  9. }