博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
springmvc源码解析MvcNamespaceHandler之<mvc:view-resolvers>
阅读量:5904 次
发布时间:2019-06-19

本文共 8337 字,大约阅读时间需要 27 分钟。

hot3.png

说在前面

本次主要介绍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 resolvers = new ManagedList(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
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
list = new ManagedList(1); list.add(beanDef);// 视图解析器的使用顺序 compositeResolverBeanDef.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE); compositeResolverBeanDef.getPropertyValues().add("viewResolvers", list); } else { throw new IllegalArgumentException("Only one
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"));   }   if (element.hasAttribute("view-class")) {      beanDefinition.getPropertyValues().add("viewClass", element.getAttribute("view-class"));   }   if (element.hasAttribute("view-names")) {      beanDefinition.getPropertyValues().add("viewNames", element.getAttribute("view-names"));   }}

往上返回到这个方法org.springframework.web.servlet.config.ViewResolversBeanDefinitionParser#createContentNegotiatingViewResolver

private BeanDefinition createContentNegotiatingViewResolver(Element resolverElement, ParserContext context) {//    注册ContentNegotiatingViewResolver bean定义      RootBeanDefinition beanDef = new RootBeanDefinition(ContentNegotiatingViewResolver.class);      beanDef.setSource(context.extractSource(resolverElement));      beanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);      MutablePropertyValues values = beanDef.getPropertyValues();//    默认视图      List
elements = DomUtils.getChildElementsByTagName(resolverElement, "default-views"); if (!elements.isEmpty()) { ManagedList
list = new ManagedList(); 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")) { 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(ParserContext context) {      String name = AnnotationDrivenBeanDefinitionParser.HANDLER_MAPPING_BEAN_NAME;      if (context.getRegistry().containsBeanDefinition(name)) {         BeanDefinition handlerMappingBeanDef = context.getRegistry().getBeanDefinition(name);//       从RequestMappingHandlerMapping bean定义中获取         return handlerMappingBeanDef.getPropertyValues().get("contentNegotiationManager");      }      name = AnnotationDrivenBeanDefinitionParser.CONTENT_NEGOTIATION_MANAGER_BEAN_NAME;      if (context.getRegistry().containsBeanDefinition(name)) {         return new RuntimeBeanReference(name);      }      return null;   }

往上返回到这个方法org.springframework.web.servlet.config.ViewResolversBeanDefinitionParser#parse

 

说到最后

本次源码解析仅代表个人观点,仅供参考。

 

转载于:https://my.oschina.net/u/3775437/blog/3023917

你可能感兴趣的文章
12行代码的相关节点
查看>>
6大设计原则
查看>>
Github简介
查看>>
存储过程—导出table数据为inser sqlt语句
查看>>
Windows 7下Maven3.0.3的安装
查看>>
CISCO2691的OSPF点对点密文测评测试
查看>>
POJ 1661 Help Jimmy(递推DP)
查看>>
Node.js 中文学习资料和教程导航
查看>>
查找(AVL平衡二叉树)
查看>>
Javascript函数调用的四种模式
查看>>
用 Asterisk 搭建自己的免费 VoIP 服务器
查看>>
lua笔记二 赋值语句
查看>>
Android 中 Internal Storage 和 External Storage 的区别
查看>>
移动端拖拽(模块化开发,触摸事件,webpack)
查看>>
spring配置和注解事务同时存在导致的事务嵌套
查看>>
AE要素选择(点选和拉框选择)
查看>>
AJAX-初学AJAX本地环境配置
查看>>
VSCode调试配置
查看>>
前端MVC学习总结(三)——AngularJS服务、路由、内置API、jQueryLite
查看>>
Selenium Web 自动化 - 项目持续集成(进阶)
查看>>