说在前面
  
  本次主要介绍springmvc配置解析。
  
  springmvc配置解析
  
  本次介绍MvcNamespaceHandler。
  
  进入到这个方法org.springframework.web.servlet.config.ViewResolversBeanDefinitionParser#parse
  
  public BeanDefinition parse(Element element, ParserContext context) {
  
  Object source = context.extractSource(element);
  
  context.pushContainingComponent(new CompositeComponentDefinition(element.getTagName(), source));
  
  ManagedList<Object> resolvers = new ManagedList<Object>(4);
  
  resolvers.setSource(context.extractSource(element));
  
  // 支持以下视图
  
  String[] names = new String[] {"jsp", "tiles", "bean-name", "freemarker", "velocity", "groovy", "script-template", "bean", "ref"};
  
  for (Element resolverElement : DomUtils.getChildElementsByTagName(element, names)) {
  
  String name = resolverElement.getLocalName();
  
  if ("bean".equals(name) || "ref".equals(name)) {
  
  resolvers.add(context.getDelegate().parsePropertySubElement(resolverElement, null));
  
  continue;
  
  }
  
  RootBeanDefinition resolverBeanDef;
  
  if ("jsp".equals(name)) {
  
  // 注册InternalResourceViewResolver视图解析器bean定义
  
  resolverBeanDef = new RootBeanDefinition(InternalResourceViewResolver.class);
  
  // 视图文件前缀
  
  resolverBeanDef.getPropertyValues().add("prefix", "/WEB-INF/");
  
  // 视图文件后缀
  
  resolverBeanDef.getPropertyValues().add("suffix", ".jsp");
  
  // 添加基于url的视图属性 ->
  
  addUrlBasedViewResolverProperties(resolverElement, resolverBeanDef);
  
  }
  
  else if ("tiles".equals(name)) {
  
  resolverBeanDef = new RootBeanDefinition(TilesViewResolver.class);
  
  addUrlBasedViewResolverProperties(resolverElement, resolverBeanDef);
  
  }
  
  else if ("freemarker".equals(name)) {
  
  // 解析FreeMarkerViewResolver bean定义
  
  resolverBeanDef = new RootBeanDefinition(FreeMarkerViewResolver.class);
  
  resolverBeanDef.getPropertyValues().add("suffix", ".ftl");
  
  addUrlBasedViewResolverProperties(resolverElement, resolverBeanDef);
  
  }
  
  else if ("velocity".equals(name)) {
  
  // 解析VelocityViewResolver bean定义
  
  resolverBeanDef = new RootBeanDefinition(org.springframework.web.servlet.view.velocity.VelocityViewResolver.class);
  
  resolverBeanDef.getPropertyValues().add("suffix", ".vm");
  
  addUrlBasedViewResolverProperties(resolverElement, resolverBeanDef);
  
  }
  
  else if ("groovy".equals(name)) {
  
  resolverBeanDef = new RootBeanDefinition(GroovyMarkupViewResolver.class);
  
  resolverBeanDef.getPropertyValues().add("suffix", ".tpl");
  
  addUrlBasedViewResolverProperties(resolverElement, resolverBeanDef);
  
  }
  
  else if ("script-template".equals(name)) {
  
  resolverBeanDef = new RootBeanDefinition(ScriptTemplateViewResolver.class);
  
  addUrlBasedViewResolverProperties(resolverElement, resolverBeanDef);
  
  }
  
  else if ("bean-name".equals(name)) {
  
  // 解析BeanNameViewResolver bean定义
  
  resolverBeanDef = new RootBeanDefinition(BeanNameViewResolver.class);
  
  }
  
  else {
  
  // Should never happen
  
  throw new IllegalStateException("Unexpected element name: " + name);
  
  }
  
  resolverBeanDef.setSource(source);
  
  resolverBeanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
  
  resolvers.add(resolverBeanDef);
  
  }
  
  String beanName = VIEW_RESOLVER_BEAN_NAME;
  
  // 解析ViewResolverComposite bean定义
  
  RootBeanDefinition compositeResolverBeanDef = new RootBeanDefinition(ViewResolverComposite.class);
  
  compositeResolverBeanDef.setSource(source);
  
  compositeResolverBeanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
  
  names = new String[] {"content-negotiation"};
  
  List<Element> contentNegotiationElements = DomUtils.getChildElementsByTagName(element, names);
  
  if (contentNegotiationElements.isEmpty()) {
  
  compositeResolverBeanDef.getPropertyValues().add("viewResolvers", resolvers);
  
  }
  
  else if (contentNegotiationElements.size() == 1) {
  
  // 创建媒体类型视图解析器 ->
  
  BeanDefinition beanDef = createContentNegotiatingViewResolver(contentNegotiationElements.get(0), context);
  
  // 组合视图解析器,解析viewResolvers属性值
  
  beanDef.getPropertyValues().add("viewResolvers", resolvers);
  
  ManagedList<Object> list = new ManagedList<Object>(1);
  
  list.add(beanDef);
  
  // 视图解析器的使用顺序
  
  compositeResolverBeanDef.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
  
  compositeResolverBeanDef.getPropertyValues().add("viewResolvers", list);
  
  }
  
  else {
  
  throw new IllegalArgumentException("Only one <content-negotiation> element is allowed.");
  
  }
  
  if (element.hasAttribute("order")) {
  
  compositeResolverBeanDef.getPropertyValues().add("order", element.getAttribute("order"));
  
  }
  
  // 注册mvcViewResolver bean定义
  
  context.getReaderContext().getRegistry().registerBeanDefinition(beanName, compositeResolverBeanDef);
  
  context.registerComponent(new BeanComponentDefinition(compositeResolverBeanDef, beanName));
  
  context.popAndRegisterContainingComponent();
  
  return null;
  
  }
  
  进入到这个方法org.springframework.web.servlet.config.ViewResolversBeanDefinitionParser#addUrlBasedViewResolverProperties
  
  private void addUrlBasedViewResolverProperties(Element element, RootBeanDefinition beanDefinition) {
  
  if (element.hasAttribute("prefix")) {
  
  beanDefinition.getPropertyValues().add("prefix", element.getAttribute("prefix"));
  
  }
  
  if (element.hasAttribute("suffix")) {
  
  beanDefinition.getPropertyValues().add("suffix", element.getAttribute("suffix"));
  
  }
  
  if (element.hasAttribute("cache-views")) {
  
  beanDefinition.getPropertyValues().add("cache", element.getAttribute("cache-views"));
  
  http://dasheng178.com/#portal/list.html
  
  if (element.hasAttribute("view-class")) {
  
  beanDefinition.getPropertyValues().add("viewClass", element.getAttribute("view-class"));
  
  }
  
  if (element.hasAttribute("view-names")) {
  
  beanDefinition.getPropertyValues().add("viewNames", element.getAttribute(www.365soke.com/"view-names"));
  
  }
  
  }
  
  往上返回到这个方法org.springframework.web.servlet.config.ViewResolversBeanDefinitionParser#createContentNegotiatingViewResolver
  
  private BeanDefinition createContentNegotiatingViewResolver(Element resolverElement, ParserContext context) {
  
  // 注册ContentNegotiatingViewResolver bean定义
  
  RootBeanDefinition beanDef =www.sanxingyLzc.com new RootBeanDefinition(ContentNegotiatingViewResolver.class);
  
  beanDef.setSource(context.extractSource(resolverElement));
  
  beanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
  
  MutablePropertyValues values www.suoLaieyuLe.com= beanDef.getPropertyValues();
  
  // 默认视图
  
  List<Element> elements = DomUtils.getChildElementsByTagName(www.yongshiyule178.com resolverElement, "default-views");
  
  if (!elements.isEmpty()) {
  
  ManagedList<Object> list = new ManagedList<Object>();
  
  for (Element element : DomUtils.getChildElementsByTagName(elements.get(0), "bean", "ref")) {
  
  list.add(context.getDelegate().parsePropertySubElement(element, null));
  
  }
  
  values.add("defaultViews", list);
  
  }
  
  // 是否开启不接受设置
  
  if (resolverElement.hasAttribute("use-not-acceptable"www.meiwanyule.cn)) {
  
  values.add("useNotAcceptableStatusCode", resolverElement.getAttribute("use-not-acceptable"));
  
  }
  
  // 获取媒体类型管理器bean定义 ->
  
  Object manager = MvcNamespaceUtils.getContentNegotiationManager(context);
  
  if (manager != null) {
  
  values.add("contentNegotiationManager", manager);
  
  }
  
  return beanDef;
  
  }
  
  进入到这个方法org.springframework.web.servlet.config.MvcNamespaceUtils#getContentNegotiationManager
  
  public static Object getContentNegotiationManager(www.michenggw.com ParserContext context) {
  
  String name = AnnotationDrivenBeanDefinitionParser.HANDLER_MAPPING_BEAN_NAME;
  
  if (context.getRegistry(www.yongshi123.cn).containsBeanDefinition(name)) {
  
  BeanDefinition handlerMappingBeanDef = context.getRegistry(www.hengy178.com).getBeanDefinition(name);
  
  // 从RequestMappingHandlerMapping bean定义中获取
  
  return handlerMappingBeanDef.getPropertyValues(www.sanxinyuLevip.com).get("contentNegotiationManager");
  
  }
  
  name = AnnotationDrivenBeanDefinitionParser.CONTENT_NEGOTIATION_MANAGER_BEAN_NAME;
  
  if (context.getRegistry(www.wanmeiyulept.com).containsBeanDefinition(name)) {
  
  return new RuntimeBeanReference(name);
  
  }
  
  return null;
  
  }
  
  往上返回到这个方法org.springframework.web.servlet.config.ViewResolversBeanDefinitionParser#parse
  
  说到最后
  
  本次源码解析仅代表个人观点,仅供参考。

springmvc源码解析MvcNamespaceHandler之<mvc:view-resolvers>的更多相关文章

  1. springMVC源码解析--ViewResolver视图解析器执行(三)

    之前两篇博客springMVC源码分析--ViewResolver视图解析器(一)和springMVC源码解析--ViewResolverComposite视图解析器集合(二)中我们已经简单介绍了一些 ...

  2. SpringMVC源码解析- HandlerAdapter - ModelFactory(转)

    ModelFactory主要是两个职责: 1. 初始化model 2. 处理器执行后将modle中相应参数设置到SessionAttributes中 我们来看看具体的处理逻辑(直接充当分析目录): 1 ...

  3. SpringMVC源码解析- HandlerAdapter - ModelFactory

    ModelFactory主要是两个职责: 1. 初始化model 2. 处理器执行后将modle中相应参数设置到SessionAttributes中 我们来看看具体的处理逻辑(直接充当分析目录): 1 ...

  4. SpringMVC源码解析

    一:springmvc运行过程: 1. dispatcherServlet 通过 HandlerMapping 找到controller2. controller经过后台逻辑处理得到结果集modela ...

  5. springMVC源码解析--ViewResolverComposite视图解析器集合(二)

    上一篇博客springMVC源码分析--ViewResolver视图解析器(一)中我们介绍了一些springMVC提供的很多视图解析器ViewResolver,在开发的一套springMVC系统中是可 ...

  6. 深入了解SpringMVC源码解析

    Spring MVC源码解析 Spring MVC的使用原理其实是通过配置一个Servlet来接管所有的请求,所有的请求由这个Servlet来进行分发处理. 我们可以从web.xml里面看出这一点 & ...

  7. springMVC源码解析--HandlerMethodArgumentResolverComposite参数解析器集合(二)

    上一篇博客springMVC源码分析--HandlerMethodArgumentResolver参数解析器(一)中我们已经介绍了参数解析相关的东西,并且也提到了HandlerMethodArgume ...

  8. SpringMVC源码解析- HandlerAdapter初始化

    HandlerAdapter初始化时,主要是进行注解解析器初始化注册;返回值处理类初始化;全局注解@ControllerAdvice内容读取并缓存. 目录: 注解解析器初始化注册:@ModelAttr ...

  9. SpringMVC 源码解析

    前言         年初面试时接触到一道面试题,在聊到SpringMVC时提到了SpringMVC的开发者为何要设计父子容器呢,又或者说是父子容器的设计有什么更实际的作用呢?          首先 ...

随机推荐

  1. 在WPF中使用FontAwesome图标字体

    原文:在WPF中使用FontAwesome图标字体 版权声明:原创内容转载必须注明出处,否则追究相关责任. https://blog.csdn.net/qq_36663276/article/deta ...

  2. 【APIO2016】烟火表演

    题面 题解 神仙题目啊QwQ 设\(f_i(x)\)表示以第\(i\)个点为根的子树需要\(x\)秒引爆的代价. 我们发现,这个函数是一个下凸的一次分段函数. 考虑这个函数合并到父亲节点时会发生怎样的 ...

  3. [Entity Framework+MVC复习总结1]-WebForm与Asp.Net MVC

    一.Web开发方式的比较 二.web Form开发模型 WebForm开发优点: 1.支持事件模型开发.得益于丰富的服务器端组件,webfrom开发可以迅速的搭建web应用 2.使用方便,入门容易 3 ...

  4. zabbix中配置当memory剩余不足20%时触发报警

    在zabbix中默认当内存剩余量不足2G的时候触发报警,并没有使用百分比来触发如下: 现在需要配置:当memory剩余不足20%时触发报警,具体操作方法如下: 1)创建itemConfiguratio ...

  5. Jmeter(非GUI模式)教程

    前言 使用非 GUI 模式,即命令行模式运行 JMeter 测试脚本能够大大缩减所需要的系统资源.优点如下:1.节约系统资源:无需启动界面,节约系统资源 2.便捷快速:仅需启动命令行,输入命令便可执行 ...

  6. 《linux内核设计与实现》第五章

    第五章 系统调用 一.与内核通信 系统调用在用户空间进程和硬件设备之间添加了一个中间层.作用: 为用户空间提供了一种硬件的抽象接口. 系统调用保证了系统的稳定和安全. 每个进程都运行在虚拟系统中,而在 ...

  7. 基于SSH的高校网上选课系统的质量属性的实现

    我对于基于SSH的高校网上选课系统的质量属性的实现是从可用性.性能.安全性.可维护性.易用性五个方面进行的实现. 可用性方面: 实现方式:(1)当系统试图超出限制范围来进行课程查询或选课时必须进行错误 ...

  8. 手工编程:hello world

    全部用命令行工具和Notepad编辑器,用手工创建并编译一个C的命令行程序:hello world. public class Hello{         public static void ma ...

  9. BETA 版冲刺前准备

    任务博客 组长博客 总的来讲Alpha阶段我们计划中的工作是如期完成的.不过由于这样那样的原因,前后端各个任务完成度不算非常高,距离完成一个真正好用.完美的软件还有所差距. 过去存在的问题 测试工作未 ...

  10. linux 清空history以及记录原理

    1.当前session执行的命令,放置缓存中,执行exit时,把缓存信息写入~/.bash_history 2.当session直接被kill时,缓存中的历史命令不会写入~/.bash_history ...