公众号,欢迎关注

HandlerMethodArgumentResolver 是一个策略接口,用来将方法的参数解析为参数的值,HandlerMethodArgumentResolver 有很多的实现类,比如
RequestParamMethodArgumentResolverRequestHeaderMethodArgumentResolverPathVariableMethodArgumentResolverMatrixVariableMethodArgumentResolver- … 还有很多,可以通过查看源代码查看
还有一个很特殊的实现 HandlerMethodArgumentResolverComposite,HandlerMethodArgumentResolverComposite 实现了 HandlerMethodArgumentResolver 接口,但却没有实现具体的参数解析策略,而是将所有的具体策略都组合到了 HandlerMethodArgumentResolverComposite 中
HandlerMethodArgumentResolverComposite 是一个典型的组合模式的实现,从类的名称也能看出一二
这样实现有什么好处呢?
组合模式有三个好处
- 去除重复代码
- 统一客户端的代码调用
- 支持对象树的处理(《重构到模式》 7.5 节有一个完美的例子)
在我看来,这里组要是体现了第二个好处,就是统一客户端的代码调用,客户只要通过与 HandlerMethodArgumentResolverComposite 进行交互即可,不需要了解具体的策略类型,对策略的选择交给 HandlerMethodArgumentResolverComposite 类进行处理
HandlerMethodArgumentResolverComposite 将客户端与具体的策略实现进行了隔离,通过 HandlerMethodArgumentResolverComposite 可以对具体的策略进行扩展而客户端无感知,也是开闭原则(OCP)的一个体现
从源码中也可以看到,几乎所有使用 HandlerMethodArgumentResolver 的地方都是实例化的 HandlerMethodArgumentResolverComposite 对象,然后将其他需要用到的具体策略添加到 HandlerMethodArgumentResolverComposite 的对象实例中
还有其他地方也用了一模一样的实现方式,例如
HandlerMethodReturnValueHandlerComposite实现了HandlerMethodReturnValueHandlerHandlerExceptionResolverComposite实现了HandlerExceptionResolverWebMvcConfigurerComposite实现了WebMvcConfigurer
实现模式也比较简单,composite 对象遍历具体的策略,调用策略接口提供 support 方法,support 方法返回自己是否支持当前的处理,如果支持则调用策略方法进行处理,如果不支持则继续向后遍历
下面便是一段典型的实现
/**
* Iterate over registered
* {@link HandlerMethodArgumentResolver HandlerMethodArgumentResolvers} and
* invoke the one that supports it.
* @throws IllegalStateException if no suitable
* {@link HandlerMethodArgumentResolver} is found.
*/
@Override
@Nullable
public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);
if (resolver == null) {
throw new IllegalArgumentException(
"Unsupported parameter type [" + parameter.getParameterType().getName() + "]." +
" supportsParameter should be called first.");
}
return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
}
/**
* Find a registered {@link HandlerMethodArgumentResolver} that supports
* the given method parameter.
*/
@Nullable
private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {
HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter);
if (result == null) {
for (HandlerMethodArgumentResolver methodArgumentResolver : this.argumentResolvers) {
if (methodArgumentResolver.supportsParameter(parameter)) {
result = methodArgumentResolver;
this.argumentResolverCache.put(parameter, result);
break;
}
}
}
return result;
}
工作中有类似的需求我们可以进行借鉴
该博客探讨了组合模式在Spring MVC中的应用,强调了它如何统一客户端代码调用,实现策略选择的隔离,并促进了策略的扩展。文章提到了`HandlerMethodArgumentResolverComposite`类作为组合模式的实例,通过这个类可以处理多种参数解析策略,遵循了开闭原则(OCP)。此外,文中还展示了组合模式的一般实现方式,并鼓励在实际工作中借鉴这种设计。

599

被折叠的 条评论
为什么被折叠?



