說在前面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
本次源碼解析僅表明我的觀點,僅供參考。