目录
1.DEBUG 注册代码
1.1 WebMvcConfigurerComposite
1.2 DelegatingWebMvcConfiguration
1.3 AutowiredAnnotationBeanPostProcessor
2.DEBUG调用代码
2.1 this.argumentResolvers
日常工作开发中,总有一些参数,在未传参数时,需要自定义一些参数。
比如
@DefaultValueIfNull("1000")
未传值时,默认加1000,用字符串是因为以后想要匹配更多类型。
这时候需要定义一个 HandlerMethodArgumentResolver
@Component
public class DefaultValueIfNullResolver implements HandlerMethodArgumentResolver {
/**
* 对参数进行默认操作,如果为空值,那么就需要进行特殊操作了
**/
private RequestParamMethodArgumentResolver argumentResolver = new RequestParamMethodArgumentResolver(false);
/**
* 是否有这个注解
* @author
* @date 2022-12-05 17:47
**/
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(DefaultValueIfNull.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
// 1. 获取到 request 对象
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
String name = parameter.getParameter().getName();
// 2.
// 得到 DefaultValueIfNull 注解,对注解进行分析,然后操作
DefaultValueIfNull defaultValueIfNull = parameter.getParameterAnnotation(DefaultValueIfNull.class);
/** 获取是什么类型的属性 **/
Class> type1 = parameter.getParameter().getType();
String value = defaultValueIfNull.value();
Class type = defaultValueIfNull.type();
return null;
}
}
注意,上面代码并没有完成,只是作为示例。
这时候就有一个疑问,这个自定义的resolver是如何添加到spring mvc框架里的。
当然,我们需要进行配置。
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private DefaultValueIfNullResolver resolver;
@Override
public void addArgumentResolvers(List resolvers) {
resolvers.add(resolver);
}
}
类路径
org.springframework.web.servlet.config.annotation.WebMvcConfigurerComposite
将 WebMvcConfigurer的各种实现类,放到 delegates里
继续向下
org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration
可以看到,这里是使用Spring容器进行操作的
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
这个类的的结构图,参看下列
AutowiredAnnotationBeanPostProcessor实现了BeanPostProcessor接口,当 Spring 容器启动时,AutowiredAnnotationBeanPostProcessor 将扫描 Spring 容器中所有 Bean,当发现 Bean 中拥有@Autowired 注解时就找到和其匹配(默认按类型匹配)的 Bean,并注入到对应的地方中去。先来看下buildAutowiringMetadata方法
这是正常的生命周期操作。
到了第一步,就知道已经注册到容器里,但是自定义resolver是何时调用的呢 ?
那么需要关注
DelegatingWebMvcConfiguration
org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport
在 WebMvcConfigurationSupport 这个配置类,可以看到
RequestMappingHandlerAdapter
这个方法,返回了一个handlerAdapter,在这里进行了操作。
进入这个方法,可以看到初始化的操作。
下面进入 addArgumentResolvers
这个 this.configurers 在 [ 1.2 DelegatingWebMvcConfiguration ]
看类型继承,可以看到
DelegatingWebMvcConfiguration 的大部分配置都是在父类 WebMvcConfigurationSupport 里进行定义了,这也是典型的模板方法。
我们继续进入到
addArgumentResolvers
内部方法里。
关于 this.delegates 查看 1.1 WebMvcConfigurerComposite
这里实际上是调用了WebMvcConfigurer的实现类的 addArgumentResolvers方法。
也就是自定义WebMvcConfig里面的代码。
Listresolvers 具体看 2.1 this.argumentResolvers
最终