说在前面web
本次主要介绍springmvc配置解析。spring
springmvc配置解析mvc
本次介绍MvcNamespaceHandler。app
进入到这个方法org.springframework.web.servlet.config.ViewResolversBeanDefinitionParser#parsejsp
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#addUrlBasedViewResolverPropertiesurl
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#createContentNegotiatingViewResolverspa
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<Element> elements = DomUtils.getChildElementsByTagName(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")) { 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#getContentNegotiationManagerip
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#parseci
说到最后element
本次源码解析仅表明我的观点,仅供参考。