文章目录

  • 1. 前言
  • 2. MvcNamespaceHandler
  • 3、AnnotationDrivenBeanDefinitionParser
  • 4、总结

1. 前言

我们经常使用 mvc:annotation-driven 这个配置,那么这个配置到底是做什么的呢?

主要用于spring mvc 中的annotation注解功能,作用是帮我们注入一些内置bean,例如RequestMappingHandlerMappingRequestMappingHandlerAdapter等,这些类是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 配置详解相关推荐

  1. Spring MVC原理及配置详解

    转载自 http://blog.csdn.net/jianyuerensheng/article/details/51258942 [Spring]Spring MVC原理及配置 1.Spring M ...

  2. 【Spring】Spring MVC原理及配置详解

    [Spring]Spring MVC原理及配置 1.Spring MVC概述: Spring MVC是Spring提供的一个强大而灵活的web框架.借助于注解,Spring MVC提供了几乎是POJO ...

  3. 轻量级数据库sqlite,spring boot+sqlite的配置详解 (一)

    spring boot+sqlite的配置,及成功运行详解 sqlite数据库的安装与调试 首先,通过sqlite官方地址下载对应的安装包 https://www.sqlite.org/downloa ...

  4. 轻量级数据库sqlite,spring boot+sqlite的配置详解 (二)

    轻量级数据库sqlite,spring boot+sqlite的配置详解 (二) 轻量级数据库sqlite,spring boot+sqlite的配置详解 (一) 首先,需要创建一个spring bo ...

  5. Spring MVC 框架搭建及详解

    现在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是作为一名程序员需要掌握的主流框架,框架选择多了,应对多变的需求和业务时,可实行的方案自然就多了.不过 ...

  6. Spring MVC的处理流程详解

    本文来说下Spring MVC 的处理流程是怎样的 文章目录 Spring MVC概述 Spring MVC的处理流程 曾经的王者-Servlet 想要更进一步 Spring MVC-两级控制器方式 ...

  7. Spring MVC 拦截器 interceptor 详解

    Spring MVC-拦截器 今天就是把有关拦截器的知识做一个总结. 1.拦截器概述 1.1 什么是拦截器? Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(F ...

  8. Spring MVC 之@Controller@RequestMapping详解

    一:配置web.xml 1)问题:spring项目中有多个配置文件mvc.xml   dao.xml 2)解决:在web.xml中 <init-param> <param-name& ...

  9. Spring MVC之@RequestBody, @ResponseBody 详解

    引言: 接上一篇文章讲述处理@RequestMapping的方法参数绑定之后,详细介绍下@RequestBody.@ResponseBody的具体用法和使用时机: 简介: @RequestBody 作 ...

  10. Spring声明式事务配置详解

    事务管理是企业级应用程序开发中必备技术,用来确保数据的完整性和一致性.本文主要讲解事务涉及到一些概念以及spring中事务的使用.如有理解偏颇之处,恳请各位大神指正,小编不胜感激! 1.何为事务?   ...

最新文章

  1. 金山android 杀毒软件,金山手机卫士
  2. Python 为什么要保留显式的 self ?
  3. gradle常用命令
  4. leetcode讲解--566. Reshape the Matrix
  5. 2021HDU多校8 - 7057 Buying Snacks(矩阵快速幂套NTT优化dp)
  6. 运算符的优先级总能起作用吗?
  7. java ssl 无证书_java – 如何修复SSL – 没有可用的证书
  8. Java案例:文件切割与合并
  9. Lorenz.m的Matlab,matlab
  10. PTA——堆中的路径
  11. 【Shiro第八篇】SpringBoot + Shiro使用Shiro标签
  12. java 排队实现_Java实现排队论的原理
  13. haneWIN Software NFS工具的使用
  14. 如何理解t检验、t分布、t值?
  15. 2017第八届CSTQB国际软件测试高峰论坛圆满召开
  16. 一份关于webpack2和模块打包的新手指南(一)
  17. RAID 磁盘阵列详解,RAID分类及优缺点
  18. Luat合宙ESP32C3教程-点亮ST7735驱动1.8寸TFT液晶屏
  19. php 模板对象,php面向对象--PHP模板 ppt
  20. 使用shell脚本写出乘法

热门文章

  1. 清华EMBA课程系列思考之十五 -- 企业绩效管理 -- 战略性绩效管理
  2. PCIE原理-002:PCIE地址是如何映射的
  3. C语言学习教程二C语言初探
  4. IE浏览器无法查看源文件的8大原因
  5. 给Ubuntu配置静态IP地址
  6. 达梦7数据库单机安装(命令行方式)
  7. 【正则表达式】网页上敏感词过滤背后的原理你知道吗?
  8. matlab触发 ttl,请问如何用TTL信号触发单反相机拍摄
  9. 你靠谱吗?看看“价值观”究竟有多重要
  10. C++入门(4)讲几道例题