【spring mvc】annotation-driven 配置详解
文章目录
- 1. 前言
- 2. MvcNamespaceHandler
- 3、AnnotationDrivenBeanDefinitionParser
- 4、总结
1. 前言
我们经常使用 mvc:annotation-driven 这个配置,那么这个配置到底是做什么的呢?
主要用于spring mvc 中的annotation注解功能,作用是帮我们注入一些内置bean,例如RequestMappingHandlerMapping
和 RequestMappingHandlerAdapter
等,这些类是Aware的子类,能完成特定的供能,例如:
RequestMappingHandlerMapping负责解析@RequestMapping("/helloworld")
注解。
主要是解析spring mvc的一些标签和语法!
等价于下面配置:
<!--HandlerMapping--><bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean><bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean><!-- HandlerAdapter--><bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean><bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"></bean><bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean><!-- HadnlerExceptionResolvers--><bean class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver"></bean><bean class="org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver"></bean><bean class="org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver"></bean>
从上面可以看到,RequestMapping会注册多个子类,spring会用chain链式尝试逐一匹配,RequestMappingHandlerMapping或BeanNameUrlHandlerMapping任意一个能匹配上收到的url,都可以正确处理。
下面来分析一下,首先找到 mvc 的命名空间的定义,如下图:
从上述图中可知,annotation-driven 配置的实现类应该是定义在了 MvcNamespaceHandler 类中,是不是这样的呢?下面我们看下 MvcNamespaceHandler 源码:
2. MvcNamespaceHandler
/*** {@link NamespaceHandler} for Spring MVC configuration namespace.** @author Keith Donald* @author Jeremy Grelle* @author Sebastien Deleuze* @since 3.0*/
public class MvcNamespaceHandler extends NamespaceHandlerSupport {@Overridepublic void init() {registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());registerBeanDefinitionParser("default-servlet-handler", new DefaultServletHandlerBeanDefinitionParser());registerBeanDefinitionParser("interceptors", new InterceptorsBeanDefinitionParser());registerBeanDefinitionParser("resources", new ResourcesBeanDefinitionParser());registerBeanDefinitionParser("view-controller", new ViewControllerBeanDefinitionParser());registerBeanDefinitionParser("redirect-view-controller", new ViewControllerBeanDefinitionParser());registerBeanDefinitionParser("status-controller", new ViewControllerBeanDefinitionParser());registerBeanDefinitionParser("view-resolvers", new ViewResolversBeanDefinitionParser());registerBeanDefinitionParser("tiles-configurer", new TilesConfigurerBeanDefinitionParser());registerBeanDefinitionParser("freemarker-configurer", new FreeMarkerConfigurerBeanDefinitionParser());registerBeanDefinitionParser("groovy-configurer", new GroovyMarkupConfigurerBeanDefinitionParser());registerBeanDefinitionParser("script-template-configurer", new ScriptTemplateConfigurerBeanDefinitionParser());registerBeanDefinitionParser("cors", new CorsBeanDefinitionParser());}}
从上述源码中可知 annotation-driven 配置对应的解析类 AnnotationDrivenBeanDefinitionParser 确实是定义在 MvcNamespaceHandler 的 init 方法中,那么 annotation-driven 配置实现的具体业务肯定在 AnnotationDrivenBeanDefinitionParser 类中,下面我们分析一下 AnnotationDrivenBeanDefinitionParser 源码
3、AnnotationDrivenBeanDefinitionParser
AnnotationDrivenBeanDefinitionParser 的 parse 方法实现了具体的解析逻辑,源码如下:
public BeanDefinition parse(Element element, ParserContext parserContext) {......// 定义 RequestMappingHandlerMappingRootBeanDefinition handlerMappingDef = new RootBeanDefinition(RequestMappingHandlerMapping.class);handlerMappingDef.setSource(source);handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);handlerMappingDef.getPropertyValues().add("order", 0);handlerMappingDef.getPropertyValues().add("contentNegotiationManager", contentNegotiationManager);.....// 注册 RequestMappingHandlerMapping 类型对应的 RootBeanDefinitionreaderContext.getRegistry().registerBeanDefinition(HANDLER_MAPPING_BEAN_NAME , handlerMappingDef);// 定义 RequestMappingHandlerAdapterRootBeanDefinition handlerAdapterDef = new RootBeanDefinition(RequestMappingHandlerAdapter.class);......// 注册 RequestMappingHandlerAdapter 对应的 RootBeanDefinitionreaderContext.getRegistry().registerBeanDefinition(HANDLER_ADAPTER_BEAN_NAME , handlerAdapterDef);
从上述源码中可以看出,在 AnnotationDrivenBeanDefinitionParser 中主要实现了注册了很多 bean 的功能,其中我们最关心的就是 RequestMappingHandlerMapping 和 RequestMappingHandlerAdapter 两个类
4、总结
Spring MVC 中如果配置了 <mvc:annotation-driven>
,则所有的 Controller 就会被解析,所以相应的 .do 请求就会被 Controller 处理,因此这个配置至关重要。当请求没有匹配到处理类(其中包括没有配置 <mvc:annotation-driven>
或者 访问的是静态资源文件)时,就会去找 <mvc:default-servlet-handler>
(处理静态资源文件)配置的 DefaultServletHttpRequestHandler 默认处理器处理了
【spring mvc】annotation-driven 配置详解相关推荐
- Spring MVC原理及配置详解
转载自 http://blog.csdn.net/jianyuerensheng/article/details/51258942 [Spring]Spring MVC原理及配置 1.Spring M ...
- 【Spring】Spring MVC原理及配置详解
[Spring]Spring MVC原理及配置 1.Spring MVC概述: Spring MVC是Spring提供的一个强大而灵活的web框架.借助于注解,Spring MVC提供了几乎是POJO ...
- 轻量级数据库sqlite,spring boot+sqlite的配置详解 (一)
spring boot+sqlite的配置,及成功运行详解 sqlite数据库的安装与调试 首先,通过sqlite官方地址下载对应的安装包 https://www.sqlite.org/downloa ...
- 轻量级数据库sqlite,spring boot+sqlite的配置详解 (二)
轻量级数据库sqlite,spring boot+sqlite的配置详解 (二) 轻量级数据库sqlite,spring boot+sqlite的配置详解 (一) 首先,需要创建一个spring bo ...
- Spring MVC 框架搭建及详解
现在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是作为一名程序员需要掌握的主流框架,框架选择多了,应对多变的需求和业务时,可实行的方案自然就多了.不过 ...
- Spring MVC的处理流程详解
本文来说下Spring MVC 的处理流程是怎样的 文章目录 Spring MVC概述 Spring MVC的处理流程 曾经的王者-Servlet 想要更进一步 Spring MVC-两级控制器方式 ...
- Spring MVC 拦截器 interceptor 详解
Spring MVC-拦截器 今天就是把有关拦截器的知识做一个总结. 1.拦截器概述 1.1 什么是拦截器? Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(F ...
- Spring MVC 之@Controller@RequestMapping详解
一:配置web.xml 1)问题:spring项目中有多个配置文件mvc.xml dao.xml 2)解决:在web.xml中 <init-param> <param-name& ...
- Spring MVC之@RequestBody, @ResponseBody 详解
引言: 接上一篇文章讲述处理@RequestMapping的方法参数绑定之后,详细介绍下@RequestBody.@ResponseBody的具体用法和使用时机: 简介: @RequestBody 作 ...
- Spring声明式事务配置详解
事务管理是企业级应用程序开发中必备技术,用来确保数据的完整性和一致性.本文主要讲解事务涉及到一些概念以及spring中事务的使用.如有理解偏颇之处,恳请各位大神指正,小编不胜感激! 1.何为事务? ...
最新文章
- 金山android 杀毒软件,金山手机卫士
- Python 为什么要保留显式的 self ?
- gradle常用命令
- leetcode讲解--566. Reshape the Matrix
- 2021HDU多校8 - 7057 Buying Snacks(矩阵快速幂套NTT优化dp)
- 运算符的优先级总能起作用吗?
- java ssl 无证书_java – 如何修复SSL – 没有可用的证书
- Java案例:文件切割与合并
- Lorenz.m的Matlab,matlab
- PTA——堆中的路径
- 【Shiro第八篇】SpringBoot + Shiro使用Shiro标签
- java 排队实现_Java实现排队论的原理
- haneWIN Software NFS工具的使用
- 如何理解t检验、t分布、t值?
- 2017第八届CSTQB国际软件测试高峰论坛圆满召开
- 一份关于webpack2和模块打包的新手指南(一)
- RAID 磁盘阵列详解,RAID分类及优缺点
- Luat合宙ESP32C3教程-点亮ST7735驱动1.8寸TFT液晶屏
- php 模板对象,php面向对象--PHP模板 ppt
- 使用shell脚本写出乘法