网站首页 > 技术教程 正文
点关注,不迷路;持续更新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容器
欢迎 你 发表评论:
- 10-23Excel计算工龄和年份之差_excel算工龄的公式year
- 10-23Excel YEARFRAC函数:时间的"年份比例尺"详解
- 10-23最常用的10个Excel函数,中文解读,动图演示,易学易用
- 10-23EXCEL中如何计算截止到今日(两个时间中)的时间
- 10-2390%人不知道的Excel神技:DATEDIF 精准计算年龄,告别手动算错!
- 10-23计算工龄及工龄工资(90%的人搞错了):DATE、DATEDIF组合应用
- 10-23Excel中如何计算工作日天数?用这两个函数轻松计算,附新年日历
- 10-23怎样快速提取单元格中的出生日期?用「Ctrl+E」批量搞定
- 最近发表
-
- Excel计算工龄和年份之差_excel算工龄的公式year
- Excel YEARFRAC函数:时间的"年份比例尺"详解
- 最常用的10个Excel函数,中文解读,动图演示,易学易用
- EXCEL中如何计算截止到今日(两个时间中)的时间
- 90%人不知道的Excel神技:DATEDIF 精准计算年龄,告别手动算错!
- 计算工龄及工龄工资(90%的人搞错了):DATE、DATEDIF组合应用
- Excel中如何计算工作日天数?用这两个函数轻松计算,附新年日历
- 怎样快速提取单元格中的出生日期?用「Ctrl+E」批量搞定
- Excel日期函数之DATEDIF函数_excel函数datedif在哪里
- Excel函数-DATEDIF求司龄_exceldatedif函数计算年龄
- 标签列表
-
- 下划线是什么 (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)

本文暂时没有评论,来添加一个吧(●'◡'●)