SPRING自定义注入CONTROLLER变量

问题描述
在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参数的解析过程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/249966.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

进程,线程

import os, timeif __name__ __main__:print(the calling process id:%d % os.getpid())# 创建进程pid os.fork()if pid 0:# 子进程print(the child pid is %d % os.getpid())time.sleep(3)elif pid > 0:# 父进程os.wait() # 等待子进程终止print([%d]bye-bye % os.getpi…

livebos--iframe使用

新建一个方法。建一个参数&#xff0c;iframe控件&#xff0c;虚拟列。然后使用以下信息 <% livebos languagejavascript %>var url LB_ObjURI("Lb_lbOrganization",0,[],["NoTitle"]);var v {"edit" : "url ", "view"…

单行溢出 和多行溢出

/*单行溢出*/.one_txt_cut{overflow: hidden;white-space: nowrap;text-overflow: ellipsis;}.txt_cut{overflow : hidden;text-overflow: ellipsis;display: -webkit-box;-webkit-line-clamp: 2;-webkit-box-orient: vertical;}转载于:https://www.cnblogs.com/smzd/p/8491583…

Spring方法注入 @Lookup注解使用

情景分析 在Spring的诸多应用场景中bean都是单例形式&#xff0c;当一个单利bean需要和一个非单利bean组合使用或者一个非单利bean和另一个非单利bean组合使用时&#xff0c;我们通常都是将依赖以属性的方式放到bean中来引用&#xff0c;然后以Autowired来标记需要注入的属性。…

Jupyter配置步骤

Jupyter是基于浏览器的可交互式开发工具&#xff0c;在数据科学界非常受欢迎&#xff0c;它功能齐全&#xff0c;使用方便&#xff0c;是一款数据分析和建模挖掘的利器。 本文简介Jupyter的配置和使用过程 一、修改添加国内镜像 通常我会先安装Anaconda&#xff0c;再安装Jupyt…

edittext 属性

1.去掉edittext的底线&#xff0c;设置&#xff0c;不管是edittext&#xff0c;还是appcompatEdittext都是这个属性 转载于:https://www.cnblogs.com/hechangshou/p/9301004.html

定义高亮颜色

/*怎么定义高亮的颜色*/-webkit-tap-highlight-color: transparent;/*透明 其实就是不显示颜色*/-webkit-tap-highlight-color: red; 转载于:https://www.cnblogs.com/smzd/p/8491587.html

springboot 配置webservice接口

导入依赖的jar <!-- webservice cxf --><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-frontend-jaxws</artifactId><version>3.1.6</version></dependency><dependency><groupId>org…

【Django】认证系统

目录 #. auth模块1. 认证 authenticate()2. 登陆 login(HttpRequest, user)3. 注销 logout(request)4. 认证判断 is_authenticated()5. 登陆校验 login_requierd()6. 创建普通用户 create_user()7. 创建超级用户 create_superuser()8. 密码校验 check_password(password)9. 修改…

学习的目的是什么?

学习的目的是为了掌握生存的常识和技能&#xff0c;以便独立地面对世界&#xff1b; 学习的目的是为了遵从生活的规范和律则&#xff0c;以便和谐地与人相处&#xff1b; 学习的目的是为了探索生命的价值和意义&#xff0c;以便有尊严地立于天地之间。 你觉得为什么要学习呢&am…

span里面插入文字

.text-box span::before{ content:attr(data-text);} 转载于:https://www.cnblogs.com/smzd/p/8491664.html

Spring Boot 动态注入的两种方式

通过Profilespring.profiles.active spring.profiles.active&#xff1a;官方解释是激活不同环境下的配置文件&#xff0c;但是实际测试发现没有对应的配置文件也是可以正常执行的。那就可以把这个key当作一个参数来使用 Profile&#xff1a;spring.profiles.active中激活某配…

kernel devel 安装与卸载

1、查看系统内核 uname -r 2、查看已安装kernel-devel uname -a ; rpm -qa kernel\* | sort 3、下载对应的rpm wget xxx/kernel-devel-2.6.32-754.el6.x86_64.rpm 或者 $ sudo yum install "kernel-devel-uname-r $(uname -r)" 4、卸载已安装的内核 yum remove ker…

弹性布局

/* 开启弹性布局的换行 */ flex-wrap: wrap;/* 变为多行了 无法使用 align-items 进行位置设置 align-content 在多行的时候 设置属性 跟 justify-content 一模一样如果只有 一行时 无法生效 *//* 调整元素 在主轴上的 排布方式flex-end 到主轴的末尾flex-start 默认值center…

详解 vue-cli 的打包配置文件代码(给大家写写注释)

一、前言 对于webpack基础不好&#xff0c;node指令不通的童鞋。估计对自己搭建Vue、react脚手架是相当头疼的&#xff0c;有种无从下手的感觉。然而&#xff0c;从头看这2块&#xff0c;耗时太长&#xff0c;而且说实话得练才行&#xff0c;不练练手看不明白。那大多数人就采取…

AutoFac自动注入时报错

错误描述&#xff1a;An error occurred during the activation of a particular registration 解决办法&#xff1a;看到了particular这个单词&#xff0c;用我蹩脚的英语&#xff0c;估计是部分类&#xff1f;结合报错的两个类存在互相引用&#xff0c;这就明白了&#xff0c…

尝试修改源码需要用到git存一下

git reflog查看本地记录 git reset --hard 02a3260 转载于:https://www.cnblogs.com/smzd/p/8492065.html

poj3713 Transferring Sylla 枚举+tarjan判割点

其实就是判断是否为三连通图 三连通图指的是去掉3个点就不连通的图&#xff0c;但是并没有直接求三连通的算法。著名的Tarjan算法可以求解连通和割点&#xff0c;再枚举删除一个点就能达到三连通的目的。 先看用例2&#xff0c;是由用例1去掉一条边而变成非三连通图的&#xff…

html标签大全

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>This is study note</title><base href"我是做外链的&#xff0c;一般在head里面" target"_blank"><style type&q…

布尔文本搜索

select text from products where Match(# column) Against(#condition bool* IN BOOLEAN MODE); 布尔操作符     包含 必须存在 -    排除,必须不存在(即使包含其他指定的词也不返回) >    增加排序等级 <    降低排序等级 ()    把词组成子表达式 …