1.背景在Spring的Controller中,我们可以通过@RequestParam或@RequestBody将request中的参数映射到控制层的具体参数,那么这是如何实现的呢?如果我当前控制层的某个参数的值来自于Redis,我该如何实现呢?2.参数是如何解析的从上图中我们的参数最终会通过HandlerMethodArgumentResolver来解析,所以知道了这些之后我们就可以实现自己的参数解析了。3、需求如果我们控制层方法的参数中有@Redis注解,那么这个参数的值应该是从redis中获取的,而不是从请求参数中获取的。从上图中我们可以看出参数@Redis(key="redisKey")StringredisValue需要从Redis中获取。4.实现这里我们并不会真正从Redis中获取值,只是模拟从Redis中获取值。1.写一个Redis注解@Target({ElementType.PARAMETER})@Retention(RetentionPolicy.RUNTIME)public@interfaceRedis{/***Keyinredis*/Stringkey();}在控制层的方法上,这里注解的方法参数都是从Redis中获取的,都是经过我们自己定义的参数解析器。2.编写参数分析类包com.huan.study.argument.resolver;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.core.MethodParameter;importorg.springframework.web.bind.support.WebDataBinderFactory;导入org.springframework.web.context.request.NativeWebRequest;导入org.springframework.web.method.support.HandlerMethodArgumentResolver;导入org.springframework.web.method.support.ModelAndViewContainer;导入javax.servquelet.http.HttpServletResolver;importjava.util.Random;/***从redis中获取值并放入参数中**/publicclassRedisMethodArgumentResolverimplementsHandlerMethodArgumentResolver{privatestaticfinalLoggerlog=LoggerFactory.getLogger(RedisMethodArgumentResolver.class);/****/@OverridepublicbooleansupportsParameter(MethodParameterparameter){returnparameter.hasParameterAnnotation(Redis.class);}/***解析参数*/@OverridepublicObjectresolveArgument(MethodParameterparameter,ModelAndViewContainermavContainer,NativeWebRequestwebRequest,WebDataBinderFactorybinderFactory)throwsException{//获取http请求HttpServletRequestrequest=webRequest.getNativeRequest(HttpServletRequest.class);log.info({"}当前请求路径"request.getRequestURI());//获取这个注解Redisredis=parameter.getParameterAnnotation(Redis.class);//获取redis中的keyStringredisKey=redis.key();//模拟从redis取值StringredisValue="从redis获取的值:"+newRandom().nextInt(100);log.info("从redis获取的值:[{}]",redisValue);//返回值returnredisValue;}}1.使用supportsParameter方法来确定我们应该处理哪些参数。在这里,我们处理带有@Redis注释的参数。2.通过resolveArgument方法获取参数的具体值。比如从Redis中获取,代码实际上并没有从Redis中获取,而是模拟从Redis中获取。3.在Spring的上下文中配置这里我们最好先把自己的参数解析器放上去,否则可能会出问题。下面提供了两种方法。第一种方式不能满足我们的需求。我们使用第二种方法实现1.Implement@ConfigurationpublicclassWebMvcConfigimplementsWebMvcConfigurerthroughWebMvcConfigurer{/***这个地方的加载顺序默认在*/HandlerMethodArgumentResolver之后@OverridepublicvoidaddArgumentResolvers(List
