网站首页 > 技术教程 正文
点关注,不迷路;持续更新Java相关技术及资讯!!!
公众号:Java大型网站架构(有免费学习资料)
工作中对于Spring MVC我们最常用的还是使用注解的方式,那么对于注解Spring MVC的如何处理的?
<context:component-scan base-package="com.demo.spring.mvc.control" /> <mvc:annotation-driven/>
一、annotation-driven
在前面的介绍中,我们知道了HandlerMapping以及HandlerAdapter,那么annotation的是什么?
对于注解:
<mvc:annotation-driven/>
它对应的handlerMapping则是:
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
对应的HandlerAdapter则是:
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
对应的Handler则是:
org.springframework.web.method.HandlerMethod
这些没有配置在配置文件中,注解是怎么实现的?
来看下NamespaceHandler接口:
org.springframework.beans.factory.xml.NamespaceHandler package org.springframework.beans.factory.xml; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinitionHolder; public interface NamespaceHandler { void init(); BeanDefinition parse(Element element, ParserContext parserContext); BeanDefinitionHolder decorate(Node source, BeanDefinitionHolder definition, ParserContext parserContext); }
实现这个接口,则就可以动态的往ioc容器添加BeanDefinition,则就动态的添加了bean。
那么这个是在哪实现的呢?
来看下spring-webmvc包里面的spring.handlers
org\springframework\spring-webmvc\4.3.8.RELEASE\spring-webmvc-4.3.8.RELEASE.jar!\META-INF\spring.handlers
里面内容:
http\://www.springframework.org/schema/mvc=org.springframework.web.servlet.config.MvcNamespaceHandler
点进去看一下 MvcNamespaceHandler 这个类:
package org.springframework.web.servlet.config; import org.springframework.beans.factory.xml.NamespaceHandlerSupport; public class MvcNamespaceHandler extends NamespaceHandlerSupport { public MvcNamespaceHandler() { } public void init() { this.registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser()); this.registerBeanDefinitionParser("default-servlet-handler", new DefaultServletHandlerBeanDefinitionParser()); this.registerBeanDefinitionParser("interceptors", new InterceptorsBeanDefinitionParser()); this.registerBeanDefinitionParser("resources", new ResourcesBeanDefinitionParser()); this.registerBeanDefinitionParser("view-controller", new ViewControllerBeanDefinitionParser()); this.registerBeanDefinitionParser("redirect-view-controller", new ViewControllerBeanDefinitionParser()); this.registerBeanDefinitionParser("status-controller", new ViewControllerBeanDefinitionParser()); this.registerBeanDefinitionParser("view-resolvers", new ViewResolversBeanDefinitionParser()); this.registerBeanDefinitionParser("tiles-configurer", new TilesConfigurerBeanDefinitionParser()); this.registerBeanDefinitionParser("freemarker-configurer", new FreeMarkerConfigurerBeanDefinitionParser()); this.registerBeanDefinitionParser("velocity-configurer", new VelocityConfigurerBeanDefinitionParser()); this.registerBeanDefinitionParser("groovy-configurer", new GroovyMarkupConfigurerBeanDefinitionParser()); this.registerBeanDefinitionParser("script-template-configurer", new ScriptTemplateConfigurerBeanDefinitionParser()); this.registerBeanDefinitionParser("cors", new CorsBeanDefinitionParser()); } }
此时我们看到了MvcNamespaceHandler extends NamespaceHandlerSupport:
public class MvcNamespaceHandler extends NamespaceHandlerSupport{...}
NamespaceHandlerSupport implements NamespaceHandler
public abstract class NamespaceHandlerSupport implements NamespaceHandler {}
NamespaceHandler接口就是我们刚刚看到的那个动态注册BeanDefinition的接口。
并且在MvcNamespaceHandler.init() 方法中,可以看到:
this.registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
并且 AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser
class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {}
其中 BeanDefinitionParser 接口:
public interface BeanDefinitionParser { BeanDefinition parse(Element element, ParserContext parserContext); }
在 AnnotationDrivenBeanDefinitionParser.parse() 的实现方法中,可以看到
RequestMappingHandlerMapping 被注册到ioc容器中:
RootBeanDefinition handlerMappingDef = new RootBeanDefinition(RequestMappingHandlerMapping.class);
同样的还有RequestMappingHandlerAdapter:
RootBeanDefinition handlerAdapterDef = new RootBeanDefinition(RequestMappingHandlerAdapter.class);
所以这就是为什么添加了 <mvc:annotation-driven/> 配置,就能实现mvc的整个配置了。
二、MVC完整的执行流程
之前我们介绍了MVC的异常处理和拦截器,那么加上这两部分,MVC的执行流程如下:
DispatcherServlet ==> 找到下面这些组件(1:n) HandlerMapping ==> 基于url找到对应的handler (其实是找到HandlerExecutionChain) HandlerAdapter ==> 基于handler找到对应的适配器 调用handler返回ModelAndView (如果出现了异常) HandlerExceptionResovler ==> 处理异常 返回errorModelAndView (如果加入了拦截器) HandlerInterceptor ==> 处理拦截器 ViewResolver ==> 视图仓库 ==> 基于viewName找到View => 解析生成Html
其中 DispatcherServlet 中调用 initStrategies 来初始化上述组件。
org.springframework.web.servlet.DispatcherServlet#initStrategies protected void initStrategies(ApplicationContext context) { this.initMultipartResolver(context); this.initLocaleResolver(context); this.initThemeResolver(context); this.initHandlerMappings(context); this.initHandlerAdapters(context); this.initHandlerExceptionResolvers(context); this.initRequestToViewNameTranslator(context); this.initViewResolvers(context); this.initFlashMapManager(context); }
关注、转发、评论头条号每天分享java 知识,
私信回复“源码”赠送Spring源码分析、Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式资料、《2019互联网大厂面试大全》
本文到这里就结束了,喜欢的朋友可以帮忙转发和关注一下,感谢支持!
猜你喜欢
- 2024-10-19 Java 项目编译提示 javax.xml.bind.annotation does not exist 错误
- 2024-10-19 Android annotation包下常用的注解
- 2024-10-19 SpringMVC疑难一:mvc:annotation-dr
- 2024-10-19 Spring 中 AnnotationConfigUtils
- 2024-10-19 spring mvc 配置失效了?(springmvc的配置)
- 2024-10-19 为什么都爱着江南?黛瓦白墙,烟雨朦胧,是文人魂牵梦绕的故乡
- 2024-10-19 Spring框架系列之构造方法底层剖析01
- 2024-10-19 基于.NET6包含DDD,ES,CQRS等概念的开源
- 2024-10-19 spring 中 AnnotationUtils 的常用方法
- 2024-10-19 SpringBoot实战4-Spring基础-IoC容器
你 发表评论:
欢迎- 最近发表
-
- Win11学院:如何在Windows 11上使用WSL安装Ubuntu
- linux移植(Linux移植freemodbus)
- 独家解读:Win10预览版9879为何无法识别硬盘
- 基于Linux系统的本地Yum源搭建与配置(ISO方式、RPM方式)
- Docker镜像瘦身(docker 减小镜像大小)
- 在linux上安装ollama(linux安装locale)
- 渗透测试系统Kali推出Docker镜像(kali linux渗透测试技术详解pdf)
- Linux环境中部署Harbor私有镜像仓库
- linux之间传文件命令之Rsync傻瓜式教程
- 解决ollama在linux中安装或升级时,通过国内镜像缩短安装时长
- 标签列表
-
- 下划线是什么 (87)
- 精美网站 (58)
- qq登录界面 (90)
- nginx 命令 (82)
- nginx .http (73)
- nginx lua (70)
- nginx 重定向 (68)
- Nginx超时 (65)
- nginx 监控 (57)
- odbc (59)
- rar密码破解工具 (62)
- annotation (71)
- 红黑树 (57)
- 智力题 (62)
- php空间申请 (61)
- 按键精灵 注册码 (69)
- 软件测试报告 (59)
- ntcreatefile (64)
- 闪动文字 (56)
- guid (66)
- abap (63)
- mpeg 2 (65)
- column (63)
- dreamweaver教程 (57)
- excel行列转换 (56)
本文暂时没有评论,来添加一个吧(●'◡'●)