问题描述
在SpringMVC中默认可以注入Model,ModelAndView,@RequestParam,@PathVariable 等,那么这个是怎么实现的,以及怎么注入一个自定义的参数呢

HandlerMethodArgumentResolver
在SpringMVC中有一个接口HandlerMethodArgumentResolver,这个就是用来控制解析controller中的参数类型来进行注入的,下面是一个自定义参数的例子
首先自定义resolver

public class MyHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {//用来判断参数是否支持当前resolver@Overridepublic boolean supportsParameter(MethodParameter parameter) {Class<?> klass = parameter.getParameterType();if (klass == String.class) {//这里使用参数类型匹配,MethodParameter还包含了方法注解和参数注解信息,可以使用它们来进行识别return true;}return false;}//真正返回要注入的值@Overridepublic Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest,WebDataBinderFactory binderFactory) throws Exception {return "custom string";}
}

注册在配置文件中

 <mvc:annotation-driven><mvc:argument-resolvers><bean class="web.controller.MyHandlerMethodArgumentResolver" /></mvc:argument-resolvers></mvc:annotation-driven>

之后就可以使用了

 @RequestMapping("test")@ResponseBodypublic String test(String a){return a;}

在页面访问test连接显示的就是自定义的“custom string”。

实现
下面来看下这个的实现,在MVC启动时会生成一个Resolver的Composite对象,这个包含了所有的注册的Resolver

在HandlerMethodArgumentResolverComposite中有如下几个方法

 //每个参数都会调用resolveArgument进行解析public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,NativeWebRequest webRequest, WebDataBinderFactory binderFactory)throws Exception {//获得对应的resolverHandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);Assert.notNull(resolver, "Unknown parameter type [" + parameter.getParameterType().getName() + "]");//使用resolver进行解析return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);}//获得相应的resolverprivate HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {//这里有个ConcurrentHashMap构成的cache可以避免重复的解析HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter);//如果cache没有命中则进行解析if (result == null) {//遍历所有resolverfor (HandlerMethodArgumentResolver methodArgumentResolver : argumentResolvers) {if (logger.isTraceEnabled()) {logger.trace("Testing if argument resolver [" + methodArgumentResolver + "] supports [" +parameter.getGenericParameterType() + "]");}//找到对应resolver并存入cacheif (methodArgumentResolver.supportsParameter(parameter)) {result = methodArgumentResolver;this.argumentResolverCache.put(parameter, result);break;}}}return result;}

那自定义的resolver是如何被springmvc探测到的呢,这里列出argumentResolvers初始化时的赋值

// Annotation-based argument resolution//基于注解的resolver明显有RequestParam,PathVariable等resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));resolvers.add(new RequestParamMapMethodArgumentResolver());resolvers.add(new PathVariableMethodArgumentResolver());resolvers.add(new ServletModelAttributeMethodProcessor(false));resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters()));resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters()));resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory()));resolvers.add(new RequestHeaderMapMethodArgumentResolver());resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory()));resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));// Type-based argument resolution//基于类型的resolver如Request,Response等resolvers.add(new ServletRequestMethodArgumentResolver());resolvers.add(new ServletResponseMethodArgumentResolver());resolvers.add(new HttpEntityMethodProcessor(getMessageConverters()));resolvers.add(new RedirectAttributesMethodArgumentResolver());resolvers.add(new ModelMethodProcessor());resolvers.add(new MapMethodProcessor());resolvers.add(new ErrorsMethodArgumentResolver());resolvers.add(new SessionStatusMethodArgumentResolver());resolvers.add(new UriComponentsBuilderMethodArgumentResolver());// Custom arguments//这里就是自定义的了resolver了if (getCustomArgumentResolvers() != null) {resolvers.addAll(getCustomArgumentResolvers());}// Catch-all//垫底的resolver,第一个RequestParamMethodArgumentResolver与前面注册的第二个构造参数不同主要用来拦截未标注注解的普通变量(如CharSequence,Number,List等)resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));resolvers.add(new ServletModelAttributeMethodProcessor(true));

总结
本文看了自定义controller参数的解析过程

SPRING自定义注入CONTROLLER变量相关推荐

  1. SpringMVC自定义注入controller变量

    问题描述 在SpringMVC中默认可以注入Model,ModelAndView,@RequestParam,@PathVariable 等,那么这个是怎么实现的,以及怎么注入一个自定义的参数呢 Ha ...

  2. Spring xml 注入静态变量

    2019独角兽企业重金招聘Python工程师标准>>> 上代码 <bean id="cacheJsonRedisSerializer" class=&quo ...

  3. 为什么不在spring容器管理controller

    Spring容器与SpringMVC容器 1.疑问:为什么不用spring去管理所有类? 我们配置springMVC 中,为什么controller不直接交给spring 管理而要spring MVC ...

  4. Spring依赖注入static静态变量相关问题

    问题:springmvc给静态变量注入报:@Autowired annotation is not supported on static fields 原因:spring annotation不支持 ...

  5. Spring 依赖注入详解

    一.IOC 依赖注入 1.什么是Spring的依赖注入 依赖注入,是IOC的一个方面,是个通常的概念,它有多种解释.这概念是说你不用创建对象,而只需要描述它如何被创建.你不在代码里直接组装你的组件和服 ...

  6. Spring中的Controller ,Service,Dao是不是线程安全的?

    作者:myseries cnblogs.com/myseries/p/11729800.html 结论:不是线程安全的 Spring容器中的Bean是否线程安全,容器本身并没有提供Bean的线程安全策 ...

  7. arg是什么函数_java后端开发三年!你还不了解Spring 依赖注入,凭什么给你涨薪...

    前言 前两天和一个同学吃饭的时候同学跟我说了一件事,说他公司有个做了两年的人向他提出要涨薪资,他就顺口问了一个问题关于spring依赖注入的,那个要求涨薪的同学居然被问懵了...事后回家想了想这一块确 ...

  8. diy实现spring依赖注入

    [README] 本文diy代码实现了 spring 依赖注入,一定程度上揭示了依赖注入原理: [1]控制反转-Inversion of Control 是一种编码思想,简而言之就是 应用程序A可以使 ...

  9. Spring 依赖注入的理解及三种注入方式

    Spring 依赖注入概念和三种注入方式(理解及应用) 什么是注入 要了解Spring的三种注入方式首先前提是得先了解一下什么是注入,相信很多人对这个概念都是模糊不清的,网上的解释是这样的: 依赖注入 ...

最新文章

  1. linux命令行模式连接网络,centos命令行模式连接无线网络的过程
  2. 硅谷顶级VC:“S曲线”看四大风口,创企成功机会巨大
  3. 太慢不能忍!CPU又拿硬盘和网卡开刀了!
  4. NeHe教程Qt实现——lesson15
  5. opencv java 摄像头_使用OpenCV Java创建Windows摄像头扫码程序
  6. 折叠屏来了,开发者们准备好了吗?
  7. 利用Axis2默认口令安全漏洞入侵WebService网站
  8. mysql挂载数据卷_记一次生产数据库数据文件进行分区转移
  9. php实现数字英文验证码,PHP英文数字验证码生成类
  10. wxpython滑动面板_wxpython实现按钮切换界面的方法
  11. ASP入门基础教程-VBScript概述及基本元素
  12. 如何显示mac的隐藏文件夹
  13. 解决文件名太长或文件夹路径太深无法删除
  14. 微信小程序文件大小限制
  15. 三菱plc pwm指令_三菱PLC必会编程指令汇总,收藏这些就够了!
  16. 取色器实战(Qt含源码)
  17. 将win10家庭版、教育版系统激活为win10专业版
  18. java smali_如何把java代码转换成smali代码
  19. 直播预告 | AAAI 2022:一种基于能量的主动域自适应学习方法
  20. C/C++编程笔记:浪漫流星雨装b表白程序

热门文章

  1. Ubuntu中配置FTP服务
  2. 未备案域名临时跳过备案提示_做好了网页,有域名和服务器,还要怎么搭建网站?...
  3. html5手机电商网页设计代码_Html5网站制作,干货!20个视觉体验和内容俱佳的优秀网页设计...
  4. ros创建工作空间_ROS入门学习之七Moveit机械臂控制
  5. android mdpi对应哪一个屏幕,android 常见分辨率(mdpi、hdpi 、xhdpi、xxhdpi )及屏幕适配...
  6. redis连不上java,java使用jedis连不上linux上redis服务
  7. 【theano-windows】学习笔记十九——循环神经网络
  8. Python 中的Pandas库
  9. How to ignore files and directories in subversion?
  10. JSP页面传值出现中文乱码的问题