** ❃博主首页 :**
<码到三十五>
☠博主专栏 :
<源码解读>
<面试攻关>
♝博主的话 :搬的每块砖,皆为峰峦之基;公众号搜索(码到三十五)关注这个爱发技术干货的coder,一起筑基 !
HandlerMethodArgumentResolver 是 Spring MVC 框架中的一个关键组件,用于解析控制器(Controller)方法的参数。在 Spring MVC 中,当一个请求到达时,DispatcherServlet 会负责找到对应的处理器(即控制器中的方法)来处理这个请求。在处理之前,需要解析方法的参数,这就是 HandlerMethodArgumentResolver 的作用
导读
- 一、HandlerMethodArgumentResolver简介- 二、工作原理和流程- - 1. 接口定义与功能- 2. 工作流程- - 2.1 确定解析器- 2.2 解析参数- 2.3 异常处理- 三、内置解析器- 四、自定义解析器- - 实现步骤- 常用场景- 用法方法- 五、结语
一、HandlerMethodArgumentResolver简介
HandlerMethodArgumentResolver
是 Spring MVC 提供的一个接口,用于将 HTTP 请求中的数据解析并绑定到控制器方法的参数上。它定义了两个主要的方法:
supportsParameter
和
resolveArgument
。
supportsParameter
方法用于判断当前解析器是否支持给定的方法参数,而
resolveArgument
方法则用于实际解析请求中的数据,并将其作为参数值返回。
下图是mvc处理流程:
HandlerMethodArgumentResolver 的主要职责是解析控制器方法的参数。这意味着当 Spring MVC 调用一个控制器方法时(上图第6步),它使用这个解析器来将请求中的数据(如请求参数、路径变量、请求体等)转换为方法参数的具体值
HandlerMethodArgumentResolver
是 Spring MVC 框架中的一个核心接口,其工作原理主要围绕如何将 HTTP 请求中的数据解析并绑定到控制器(Controller)方法的参数上。以下是该接口工作原理的详细介绍:
二、工作原理和流程
1. 接口定义与功能
HandlerMethodArgumentResolver
接口定义了两个主要方法:
boolean supportsParameter(MethodParameter parameter)
: 用于判断当前解析器是否支持给定的方法参数。这通常基于参数的注解或类型来决定。Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception
: 用于实际解析请求中的数据,并将其作为参数值返回。如果在解析过程中遇到错误,该方法可能会抛出异常。
2. 工作流程
当 Spring MVC 接收到一个 HTTP 请求并确定要调用的控制器方法后,它会按照以下步骤使用
HandlerMethodArgumentResolver
来解析方法的参数:
2.1 确定解析器
Spring MVC 会遍历所有已注册的
HandlerMethodArgumentResolver
实现,并调用每个解析器的
supportsParameter
方法来检查是否有解析器支持当前方法的参数。一旦找到支持的解析器,就会使用该解析器来解析参数。
2.2 解析参数
一旦确定了合适的解析器,Spring MVC 就会调用该解析器的
resolveArgument
方法来实际解析请求中的数据。这个过程可能涉及从请求头、请求体、路径变量、查询参数等不同来源提取数据,并将其转换为方法参数所需的类型。
2.3 异常处理
如果在解析过程中发生异常,解析器通常会抛出一个异常,该异常随后会被 Spring MVC 的异常处理机制捕获并处理。这允许开发者为不同的异常类型提供自定义的错误响应。
三、内置解析器
Spring MVC 提供了多种内置的
HandlerMethodArgumentResolver
实现,用于处理不同类型的请求参数,如:
ServletRequestParamMethodArgumentResolver
:解析请求参数中的查询参数。PathVariableMethodArgumentResolver
:解析请求参数中的路径变量。RequestHeaderMethodArgumentResolver
:解析请求头中的参数。RequestBodyMethodArgumentResolver
:解析请求体中的参数,通常用于处理 JSON 或 XML 数据。ServletModelAttributeMethodProcessor
:处理带有@ModelAttribute
注解的参数,用于将请求参数绑定到模型对象上。
四、自定义解析器
除了内置解析器外,Spring MVC 还允许开发者自定义
HandlerMethodArgumentResolver
实现类,以处理特殊的参数类型或实现自定义的解析逻辑。自定义解析器需要实现
HandlerMethodArgumentResolver
接口,并覆盖
supportsParameter
和
resolveArgument
方法。然后,通过注册自定义解析器到 Spring MVC 的配置中,使其能够参与到参数解析的过程中。
实现步骤
自定义HandlerMethodArgumentResolver一般包含以下步骤:
- 创建自定义解析器类,实现
HandlerMethodArgumentResolver
接口。 - 覆盖
supportsParameter
方法,定义该解析器支持的参数类型或注解。 - 覆盖
resolveArgument
方法,实现自定义的参数解析逻辑。 - 在 Spring MVC 配置中注册自定义解析器。
常用场景
自定义HandlerMethodArgumentResolver通常在以下情况下使用:
- 当需要解析的请求参数类型不是 Spring MVC 默认支持的。
- 当需要在参数解析过程中添加特定的逻辑,如权限检查、数据验证等
用法方法
下面代码中,创建一个自定义解析器来解析一个自定义的注解
@CurrentUser
,该注解用于将当前用户的信息注入到控制器方法的参数中。
首先,定义
@CurrentUser
注解:
importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;@Target(ElementType.PARAMETER)@Retention(RetentionPolicy.RUNTIME)public@interfaceCurrentUser{}
然后,创建自定义的
HandlerMethodArgumentResolver
:
importorg.springframework.core.MethodParameter;importorg.springframework.web.bind.support.WebDataBinderFactory;importorg.springframework.web.context.request.NativeWebRequest;importorg.springframework.web.method.support.HandlerMethodArgumentResolver;importorg.springframework.web.method.support.ModelAndViewContainer;importorg.springframework.stereotype.Component;@ComponentpublicclassCurrentUserArgumentResolverimplementsHandlerMethodArgumentResolver{@OverridepublicbooleansupportsParameter(MethodParameter parameter){return parameter.hasParameterAnnotation(CurrentUser.class)&& parameter.getParameterType().equals(User.class);}@OverridepublicObjectresolveArgument(MethodParameter parameter,ModelAndViewContainer mavContainer,NativeWebRequest webRequest,WebDataBinderFactory binderFactory)throwsException{// 假设已经有获取当前用户的方法User currentUser =getCurrentUser(webRequest);return currentUser;}privateUsergetCurrentUser(NativeWebRequest webRequest){// 这里是你的逻辑来获取当前用户,例如从Session或Security Context中// 返回一个新的User实例returnnewUser();}}
最后,在控制器中使用这个注解:
importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RestController;@RestControllerpublicclassUserController{@GetMapping("/user/info")publicStringgetUserInfo(@CurrentUserUser currentUser){// 这里可以使用currentUser对象,它已经被解析器填充了return"User info for: "+ currentUser.getName();}}
别忘了在Spring配置中注册这个解析器,如果使用的是Java配置,可以在配置类中添加:
importorg.springframework.context.annotation.Configuration;importorg.springframework.web.method.support.HandlerMethodArgumentResolver;importorg.springframework.web.servlet.config.annotation.WebMvcConfigurer;importjava.util.List;@ConfigurationpublicclassWebConfigimplementsWebMvcConfigurer{@AutowiredprivateCurrentUserArgumentResolver currentUserArgumentResolver;@OverridepublicvoidaddArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers){
resolvers.add(currentUserArgumentResolver);}}
这样,当访问
/user/info
端点时,
CurrentUserArgumentResolver
将会被调用,并将当前用户的信息注入到
getUserInfo
方法的
currentUser
参数中。
五、结语
HandlerMethodArgumentResolver
是 Spring MVC 框架中用于解析请求参数的关键接口。通过内置解析器和自定义解析器,Spring MVC 提供了灵活而强大的参数解析能力,使得开发者可以轻松处理各种复杂的请求参数场景。深入理解
HandlerMethodArgumentResolver
的工作原理对于掌握 Spring MVC 框架的请求处理流程和提高开发效率具有重要意义。
关注公众号获取更多技术干货 !
版权归原作者 码到三十五 所有, 如有侵权,请联系我们删除。