可以扩展 Spring MVC,自定义参数解析器,解析所需要的参数,这里模拟一个自定义注解,获取当前登录用户的逻辑
自定义注解
定义了一个自定义注解 @LoginUser 用于获取当前登录用户
@Target({ElementType.PARAMETER})@Retention(RetentionPolicy.RUNTIME)public @interface LoginUser {}
自定义参数解析器
自定义一个参数解析器,用于解析 @LoginUser 的注解,并赋值
@Componentpublic class LoginUserResolver implements HandlerMethodArgumentResolver {@Overridepublic boolean supportsParameter(MethodParameter parameter) {return parameter.hasParameterAnnotation(LoginUser.class);}@Overridepublic Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {// 从 request 或 redis 中获取用户逻辑...System.out.println("---从 request 或 redis 中获取用户逻辑---");Map<String, Object> map = new HashMap<>();map.put("sessionId", webRequest.getSessionId());map.put("id", "123456");map.put("name", "eric");return map;}}
添加参数解析器
将自定义的参数解析器添加到 argumentResolvers 列表中,我们可以通过重写 addArgumentResolvers 方法来实现
注意:
如果自定义的参数是一个 Map,List 这样的对象,很可能就会被 Spring 自带的参数解析器所解析,这样就不会使用到我们自定义的参数解析器了,所以我们要想办法,让我们的参数解析器优先级高于 Spring 自带的一系列参数解析器
@Configuration@ComponentScan("org.wesoft.mvc")@EnableWebMvc // 相当于 XML 中的 <mvc:annotation-driven/>public class AppConfig implements WebMvcConfigurer {/*** 添加参数解析器** @param resolvers initially an empty list*/@Overridepublic void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {// 这里其实是传过来一个空集合,对应着 customArgumentResolvers// 也就是我们其实是在 customArgumentResolvers 里添加自定义方法// 然后 spring mvc 会将这个集合合并到 argumentResolvers 中,所以并不能保证执行顺序resolvers.add(new LoginUserResolver());}// 会在 Spring mvc 环境初始化完成之后,加载这个方法@Autowiredpublic void iniArgumentsResolvers(RequestMappingHandlerAdapter requestMappingHandlerAdapter) {List<HandlerMethodArgumentResolver> argumentResolvers = new ArrayList<>(requestMappingHandlerAdapter.getArgumentResolvers());// 获取自定义的参数解析器List<HandlerMethodArgumentResolver> customArgumentResolvers = requestMappingHandlerAdapter.getCustomArgumentResolvers();// 删除原来集合中的自定义参数解析器argumentResolvers.removeAll(customArgumentResolvers);// 重新加入到最前面argumentResolvers.addAll(0, customArgumentResolvers);// 重新设置参数解析器requestMappingHandlerAdapter.setArgumentResolvers(argumentResolvers);}}
使用自定义注解获取当前登录用户
@RequestMapping("/test.do")@ResponseBodypublic Object test(@LoginUser Map loginUser) {System.out.println("loginUser = " + loginUser);Map<String, Object> map = new HashMap<>();map.put("name", name);map.put("userEntity", userEntity);return map;}
