springmvc原始碼解析MvcNamespaceHandler之 <mvc:annotation-driven/>一
說在前面
本次主要介紹springmvc配置解析。
springmvc配置解析
本次介紹MvcNamespaceHandler。
public void init() { registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser()); registerBeanDefinitionParser("default-servlet-handler", new DefaultServletHandlerBeanDefinitionParser()); registerBeanDefinitionParser("interceptors", new InterceptorsBeanDefinitionParser()); registerBeanDefinitionParser("resources", new ResourcesBeanDefinitionParser()); registerBeanDefinitionParser("view-controller", new ViewControllerBeanDefinitionParser()); registerBeanDefinitionParser("redirect-view-controller", new ViewControllerBeanDefinitionParser()); registerBeanDefinitionParser("status-controller", new ViewControllerBeanDefinitionParser()); registerBeanDefinitionParser("view-resolvers", new ViewResolversBeanDefinitionParser()); registerBeanDefinitionParser("tiles-configurer", new TilesConfigurerBeanDefinitionParser()); registerBeanDefinitionParser("freemarker-configurer", new FreeMarkerConfigurerBeanDefinitionParser()); registerBeanDefinitionParser("velocity-configurer", new VelocityConfigurerBeanDefinitionParser()); registerBeanDefinitionParser("groovy-configurer", new GroovyMarkupConfigurerBeanDefinitionParser()); registerBeanDefinitionParser("script-template-configurer", new ScriptTemplateConfigurerBeanDefinitionParser()); registerBeanDefinitionParser("cors", new CorsBeanDefinitionParser()); }
進入到這個方法org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#parse
接下來介紹這個標籤<mvc:annotation-driven/>原始碼解析,找到這個類org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser,這個標籤做了什麼事情呢。
預設註冊了RequestMappingHandlerMapping、BeanNameUrlHandlerMapping、RequestMappingHandlerAdapter、HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter、ExceptionHandlerExceptionResolver、ResponseStatusExceptionResolver、DefaultHandlerExceptionResolver這些元件,這些元件是幹什麼的第一篇文章有介紹。
找到這個org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#parse,由於之前spring原始碼解析的鋪墊,我們知道解析xml標籤bean定義到beanFactory會執行這個方法。載入xml解析bean定義註冊到beanFactory這裡不做詳細介紹,大家可以詳約之前的spring原始碼解析文章。
@Override public BeanDefinition parse(Element element, ParserContext context) { Object source = context.extractSource(element); // 獲取XmlReaderContext XmlReaderContext readerContext = context.getReaderContext(); CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), source); context.pushContainingComponent(compDefinition); // 請求、響應格式管理器 -> RuntimeBeanReference contentNegotiationManager = getContentNegotiationManager(element, source, context); // 註冊RequestMappingHandlerMapping bean定義 RootBeanDefinition handlerMappingDef = new RootBeanDefinition(RequestMappingHandlerMapping.class); handlerMappingDef.setSource(source); handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); // 設定順序,預設是0 handlerMappingDef.getPropertyValues().add("order", 0); // 新增依賴bean定義 handlerMappingDef.getPropertyValues().add("contentNegotiationManager", contentNegotiationManager); // 是否開啟矩陣變數查詢 if (element.hasAttribute("enable-matrix-variables")) { Boolean enableMatrixVariables = Boolean.valueOf(element.getAttribute("enable-matrix-variables")); handlerMappingDef.getPropertyValues().add("removeSemicolonContent", !enableMatrixVariables); } else if (element.hasAttribute("enableMatrixVariables")) { Boolean enableMatrixVariables = Boolean.valueOf(element.getAttribute("enableMatrixVariables")); handlerMappingDef.getPropertyValues().add("removeSemicolonContent", !enableMatrixVariables); } // -> configurePathMatchingProperties(handlerMappingDef, element, context); // 註冊RequestMappingHandlerMapping bean定義 readerContext.getRegistry().registerBeanDefinition(HANDLER_MAPPING_BEAN_NAME , handlerMappingDef); // 註冊跨域支援bean定義 -> RuntimeBeanReference corsRef = MvcNamespaceUtils.registerCorsConfigurations(null, context, source); handlerMappingDef.getPropertyValues().add("corsConfigurations", corsRef); // 型別轉換服務bean定義解析 RuntimeBeanReference conversionService = getConversionService(element, source, context); // validator bean定義解析 -> RuntimeBeanReference validator = getValidator(element, source, context); // 解析訊息編碼解析器bean定義 -> RuntimeBeanReference messageCodesResolver = getMessageCodesResolver(element); RootBeanDefinition bindingDef = new RootBeanDefinition(ConfigurableWebBindingInitializer.class); bindingDef.setSource(source); bindingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); bindingDef.getPropertyValues().add("conversionService", conversionService); bindingDef.getPropertyValues().add("validator", validator); bindingDef.getPropertyValues().add("messageCodesResolver", messageCodesResolver); // 獲取訊息轉換器 -> ManagedList<?> messageConverters = getMessageConverters(element, source, context); // 獲取引數解析器 -> ManagedList<?> argumentResolvers = getArgumentResolvers(element, context); // 獲取返回值handler -> ManagedList<?> returnValueHandlers = getReturnValueHandlers(element, context); // 獲取非同步超時時間 -> String asyncTimeout = getAsyncTimeout(element); // 獲取非同步任務執行器 -> RuntimeBeanReference asyncExecutor = getAsyncExecutor(element); // 獲取有返回值的攔截器 ManagedList<?> callableInterceptors = getCallableInterceptors(element, source, context); // 獲取延遲結果攔截器 -> ManagedList<?> deferredResultInterceptors = getDeferredResultInterceptors(element, source, context); // 註冊RequestMappingHandlerAdapter bean定義 RootBeanDefinition handlerAdapterDef = new RootBeanDefinition(RequestMappingHandlerAdapter.class); handlerAdapterDef.setSource(source); handlerAdapterDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); handlerAdapterDef.getPropertyValues().add("contentNegotiationManager", contentNegotiationManager); handlerAdapterDef.getPropertyValues().add("webBindingInitializer", bindingDef); handlerAdapterDef.getPropertyValues().add("messageConverters", messageConverters); // 新增json請求通知處理器JsonViewRequestBodyAdvice -> addRequestBodyAdvice(handlerAdapterDef); // 新增json響應通知處理器JsonViewResponseBodyAdvice -> addResponseBodyAdvice(handlerAdapterDef); // 重定向操作是否預設不帶引數 if (element.hasAttribute("ignore-default-model-on-redirect")) { Boolean ignoreDefaultModel = Boolean.valueOf(element.getAttribute("ignore-default-model-on-redirect")); handlerAdapterDef.getPropertyValues().add("ignoreDefaultModelOnRedirect", ignoreDefaultModel); } else if (element.hasAttribute("ignoreDefaultModelOnRedirect")) { // "ignoreDefaultModelOnRedirect" spelling is deprecated Boolean ignoreDefaultModel = Boolean.valueOf(element.getAttribute("ignoreDefaultModelOnRedirect")); handlerAdapterDef.getPropertyValues().add("ignoreDefaultModelOnRedirect", ignoreDefaultModel); } if (argumentResolvers != null) { handlerAdapterDef.getPropertyValues().add("customArgumentResolvers", argumentResolvers); } if (returnValueHandlers != null) { handlerAdapterDef.getPropertyValues().add("customReturnValueHandlers", returnValueHandlers); } if (asyncTimeout != null) { // 解析非同步請求超時時間 handlerAdapterDef.getPropertyValues().add("asyncRequestTimeout", asyncTimeout); } if (asyncExecutor != null) { // 註冊非同步執行緒池 handlerAdapterDef.getPropertyValues().add("taskExecutor", asyncExecutor); } handlerAdapterDef.getPropertyValues().add("callableInterceptors", callableInterceptors); handlerAdapterDef.getPropertyValues().add("deferredResultInterceptors", deferredResultInterceptors); readerContext.getRegistry().registerBeanDefinition(HANDLER_ADAPTER_BEAN_NAME , handlerAdapterDef); RootBeanDefinition uriContributorDef = new RootBeanDefinition(CompositeUriComponentsContributorFactoryBean.class); uriContributorDef.setSource(source); uriContributorDef.getPropertyValues().addPropertyValue("handlerAdapter", handlerAdapterDef); uriContributorDef.getPropertyValues().addPropertyValue("conversionService", conversionService); String uriContributorName = MvcUriComponentsBuilder.MVC_URI_COMPONENTS_CONTRIBUTOR_BEAN_NAME; readerContext.getRegistry().registerBeanDefinition(uriContributorName, uriContributorDef); // 註冊轉換服務攔截器 RootBeanDefinition csInterceptorDef = new RootBeanDefinition(ConversionServiceExposingInterceptor.class); csInterceptorDef.setSource(source); csInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, conversionService); RootBeanDefinition mappedInterceptorDef = new RootBeanDefinition(MappedInterceptor.class); mappedInterceptorDef.setSource(source); mappedInterceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, (Object) null); mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, csInterceptorDef); String mappedInterceptorName = readerContext.registerWithGeneratedName(mappedInterceptorDef); // 註冊異常請求解析器bean定義 RootBeanDefinition methodExceptionResolver = new RootBeanDefinition(ExceptionHandlerExceptionResolver.class); methodExceptionResolver.setSource(source); methodExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); methodExceptionResolver.getPropertyValues().add("contentNegotiationManager", contentNegotiationManager); methodExceptionResolver.getPropertyValues().add("messageConverters", messageConverters); methodExceptionResolver.getPropertyValues().add("order", 0); // 新增json響應通知處理器JsonViewResponseBodyAdvice addResponseBodyAdvice(methodExceptionResolver); if (argumentResolvers != null) { methodExceptionResolver.getPropertyValues().add("customArgumentResolvers", argumentResolvers); } if (returnValueHandlers != null) { methodExceptionResolver.getPropertyValues().add("customReturnValueHandlers", returnValueHandlers); } String methodExResolverName = readerContext.registerWithGeneratedName(methodExceptionResolver); // 註冊響應狀態碼異常解析器bean定義 RootBeanDefinition statusExceptionResolver = new RootBeanDefinition(ResponseStatusExceptionResolver.class); statusExceptionResolver.setSource(source); statusExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); statusExceptionResolver.getPropertyValues().add("order", 1); String statusExResolverName = readerContext.registerWithGeneratedName(statusExceptionResolver); // 註冊預設異常處理器bean定義 RootBeanDefinition defaultExceptionResolver = new RootBeanDefinition(DefaultHandlerExceptionResolver.class); defaultExceptionResolver.setSource(source); defaultExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); defaultExceptionResolver.getPropertyValues().add("order", 2); String defaultExResolverName = readerContext.registerWithGeneratedName(defaultExceptionResolver); context.registerComponent(new BeanComponentDefinition(handlerMappingDef, HANDLER_MAPPING_BEAN_NAME)); context.registerComponent(new BeanComponentDefinition(handlerAdapterDef, HANDLER_ADAPTER_BEAN_NAME)); context.registerComponent(new BeanComponentDefinition(uriContributorDef, uriContributorName)); context.registerComponent(new BeanComponentDefinition(mappedInterceptorDef, mappedInterceptorName)); context.registerComponent(new BeanComponentDefinition(methodExceptionResolver, methodExResolverName)); context.registerComponent(new BeanComponentDefinition(statusExceptionResolver, statusExResolverName)); context.registerComponent(new BeanComponentDefinition(defaultExceptionResolver, defaultExResolverName)); // Ensure BeanNameUrlHandlerMapping (SPR-8289) and default HandlerAdapters are not "turned off" 註冊預設bean定義元件 -> MvcNamespaceUtils.registerDefaultComponents(context, source); context.popAndRegisterContainingComponent(); return null; }
進入到這個方法org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#getContentNegotiationManager
private RuntimeBeanReference getContentNegotiationManager(Element element, Object source, ParserContext context) { RuntimeBeanReference beanRef; // content-negotiation-manager 標籤屬性 if (element.hasAttribute("content-negotiation-manager")) { String name = element.getAttribute("content-negotiation-manager"); beanRef = new RuntimeBeanReference(name); } else { RootBeanDefinition factoryBeanDef = new RootBeanDefinition(ContentNegotiationManagerFactoryBean.class); factoryBeanDef.setSource(source); factoryBeanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); // 新增預設的mediaTypes -> factoryBeanDef.getPropertyValues().add("mediaTypes", getDefaultMediaTypes()); String name = CONTENT_NEGOTIATION_MANAGER_BEAN_NAME; // 註冊mvcContentNegotiationManager bean定義 context.getReaderContext().getRegistry().registerBeanDefinition(name , factoryBeanDef); // 祖冊元件 context.registerComponent(new BeanComponentDefinition(factoryBeanDef, name)); beanRef = new RuntimeBeanReference(name); } return beanRef; }
進入到這個方法org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#getDefaultMediaTypes
private Properties getDefaultMediaTypes() { Properties defaultMediaTypes = new Properties(); if (romePresent) { defaultMediaTypes.put("atom", MediaType.APPLICATION_ATOM_XML_VALUE); defaultMediaTypes.put("rss", MediaType.APPLICATION_RSS_XML_VALUE); } // xml型別 jaxb jackson if (jaxb2Present || jackson2XmlPresent) { defaultMediaTypes.put("xml", MediaType.APPLICATION_XML_VALUE); } // json型別 jackson gson if (jackson2Present || gsonPresent) { defaultMediaTypes.put("json", MediaType.APPLICATION_JSON_VALUE); } return defaultMediaTypes; }
往上返回到這個方法org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#configurePathMatchingProperties
private void configurePathMatchingProperties( RootBeanDefinition handlerMappingDef, Element element, ParserContext context) { // 路徑規則檔案配置 Element pathMatchingElement = DomUtils.getChildElementByTagName(element, "path-matching"); if (pathMatchingElement != null) { Object source = context.extractSource(element); // 字尾 if (pathMatchingElement.hasAttribute("suffix-pattern")) { Boolean useSuffixPatternMatch = Boolean.valueOf(pathMatchingElement.getAttribute("suffix-pattern")); handlerMappingDef.getPropertyValues().add("useSuffixPatternMatch", useSuffixPatternMatch); } // 是否支援混合檢視 if (pathMatchingElement.hasAttribute("trailing-slash")) { Boolean useTrailingSlashMatch = Boolean.valueOf(pathMatchingElement.getAttribute("trailing-slash")); handlerMappingDef.getPropertyValues().add("useTrailingSlashMatch", useTrailingSlashMatch); } // 是否只註冊字首 if (pathMatchingElement.hasAttribute("registered-suffixes-only")) { Boolean useRegisteredSuffixPatternMatch = Boolean.valueOf(pathMatchingElement.getAttribute("registered-suffixes-only")); handlerMappingDef.getPropertyValues().add("useRegisteredSuffixPatternMatch", useRegisteredSuffixPatternMatch); } // 註冊path解析類 RuntimeBeanReference pathHelperRef = null; if (pathMatchingElement.hasAttribute("path-helper")) { pathHelperRef = new RuntimeBeanReference(pathMatchingElement.getAttribute("path-helper")); } // -> pathHelperRef = MvcNamespaceUtils.registerUrlPathHelper(pathHelperRef, context, source); handlerMappingDef.getPropertyValues().add("urlPathHelper", pathHelperRef); RuntimeBeanReference pathMatcherRef = null; // 註冊路徑匹配器 if (pathMatchingElement.hasAttribute("path-matcher")) { pathMatcherRef = new RuntimeBeanReference(pathMatchingElement.getAttribute("path-matcher")); } // -> pathMatcherRef = MvcNamespaceUtils.registerPathMatcher(pathMatcherRef, context, source); handlerMappingDef.getPropertyValues().add("pathMatcher", pathMatcherRef); } }
進入到這個方法org.springframework.web.servlet.config.MvcNamespaceUtils#registerUrlPathHelper
public static RuntimeBeanReference registerUrlPathHelper( RuntimeBeanReference urlPathHelperRef, ParserContext parserContext, Object source) { if (urlPathHelperRef != null) { if (parserContext.getRegistry().isAlias(URL_PATH_HELPER_BEAN_NAME)) { parserContext.getRegistry().removeAlias(URL_PATH_HELPER_BEAN_NAME); } // 註冊mvcUrlPathHelper別名 parserContext.getRegistry().registerAlias(urlPathHelperRef.getBeanName(), URL_PATH_HELPER_BEAN_NAME); } else if (!parserContext.getRegistry().isAlias(URL_PATH_HELPER_BEAN_NAME) && !parserContext.getRegistry().containsBeanDefinition(URL_PATH_HELPER_BEAN_NAME)) { RootBeanDefinition urlPathHelperDef = new RootBeanDefinition(UrlPathHelper.class); urlPathHelperDef.setSource(source); urlPathHelperDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); // 註冊mvcUrlPathHelper bean定義 parserContext.getRegistry().registerBeanDefinition(URL_PATH_HELPER_BEAN_NAME, urlPathHelperDef); parserContext.registerComponent(new BeanComponentDefinition(urlPathHelperDef, URL_PATH_HELPER_BEAN_NAME)); } return new RuntimeBeanReference(URL_PATH_HELPER_BEAN_NAME); }
往上返回到這個方法org.springframework.web.servlet.config.MvcNamespaceUtils#registerPathMatcher
public static RuntimeBeanReference registerPathMatcher( RuntimeBeanReference pathMatcherRef, ParserContext parserContext, Object source) { if (pathMatcherRef != null) { if (parserContext.getRegistry().isAlias(PATH_MATCHER_BEAN_NAME)) { parserContext.getRegistry().removeAlias(PATH_MATCHER_BEAN_NAME); } // 註冊別名mvcPathMatcher parserContext.getRegistry().registerAlias(pathMatcherRef.getBeanName(), PATH_MATCHER_BEAN_NAME); } else if (!parserContext.getRegistry().isAlias(PATH_MATCHER_BEAN_NAME) && !parserContext.getRegistry().containsBeanDefinition(PATH_MATCHER_BEAN_NAME)) { RootBeanDefinition pathMatcherDef = new RootBeanDefinition(AntPathMatcher.class); pathMatcherDef.setSource(source); pathMatcherDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); // 註冊mvcPathMatcher bean定義 parserContext.getRegistry().registerBeanDefinition(PATH_MATCHER_BEAN_NAME, pathMatcherDef); parserContext.registerComponent(new BeanComponentDefinition(pathMatcherDef, PATH_MATCHER_BEAN_NAME)); } return new RuntimeBeanReference(PATH_MATCHER_BEAN_NAME); }
往上返回到這個方法org.springframework.web.servlet.config.MvcNamespaceUtils#registerCorsConfigurations
public static RuntimeBeanReference registerCorsConfigurations( Map<String, CorsConfiguration> corsConfigurations, ParserContext context, Object source) { // mvcCorsConfigurations 跨域支援bean定義解析 if (!context.getRegistry().containsBeanDefinition(CORS_CONFIGURATION_BEAN_NAME)) { RootBeanDefinition corsDef = new RootBeanDefinition(LinkedHashMap.class); corsDef.setSource(source); corsDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); if (corsConfigurations != null) { corsDef.getConstructorArgumentValues().addIndexedArgumentValue(0, corsConfigurations); } // 註冊mvcCorsConfigurations bean定義 context.getReaderContext().getRegistry().registerBeanDefinition(CORS_CONFIGURATION_BEAN_NAME, corsDef); context.registerComponent(new BeanComponentDefinition(corsDef, CORS_CONFIGURATION_BEAN_NAME)); } else if (corsConfigurations != null) { BeanDefinition corsDef = context.getRegistry().getBeanDefinition(CORS_CONFIGURATION_BEAN_NAME); corsDef.getConstructorArgumentValues().addIndexedArgumentValue(0, corsConfigurations); } return new RuntimeBeanReference(CORS_CONFIGURATION_BEAN_NAME); }
往上返回到這個方法org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#getValidator
private RuntimeBeanReference getValidator(Element element, Object source, ParserContext context) { // 解析validator屬性值,註冊驗證服務 if (element.hasAttribute("validator")) { return new RuntimeBeanReference(element.getAttribute("validator")); } else if (javaxValidationPresent) { RootBeanDefinition validatorDef = new RootBeanDefinition( "org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean"); validatorDef.setSource(source); validatorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); String validatorName = context.getReaderContext().registerWithGeneratedName(validatorDef); context.registerComponent(new BeanComponentDefinition(validatorDef, validatorName)); return new RuntimeBeanReference(validatorName); } else { return null; } }
往上返回到這個方法org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#getMessageCodesResolver
private RuntimeBeanReference getMessageCodesResolver(Element element) { if (element.hasAttribute("message-codes-resolver")) { return new RuntimeBeanReference(element.getAttribute("message-codes-resolver")); } else { return null; } }
往上返回到這個方法org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#getMessageConverters
private ManagedList<?> getMessageConverters(Element element, Object source, ParserContext context) { Element convertersElement = DomUtils.getChildElementByTagName(element, "message-converters"); ManagedList<Object> messageConverters = new ManagedList<Object>(); if (convertersElement != null) { messageConverters.setSource(source); for (Element beanElement : DomUtils.getChildElementsByTagName(convertersElement, "bean", "ref")) { Object object = context.getDelegate().parsePropertySubElement(beanElement, null); messageConverters.add(object); } } // 是否註冊預設值ByteArrayHttpMessageConverter if (convertersElement == null || Boolean.valueOf(convertersElement.getAttribute("register-defaults"))) { messageConverters.setSource(source); messageConverters.add(createConverterDefinition(ByteArrayHttpMessageConverter.class, source)); // 註冊StringHttpMessageConverter bean定義 RootBeanDefinition stringConverterDef = createConverterDefinition(StringHttpMessageConverter.class, source); stringConverterDef.getPropertyValues().add("writeAcceptCharset", false); messageConverters.add(stringConverterDef); // 新增預設轉換器 messageConverters.add(createConverterDefinition(ResourceHttpMessageConverter.class, source)); messageConverters.add(createConverterDefinition(SourceHttpMessageConverter.class, source)); // -> messageConverters.add(createConverterDefinition(AllEncompassingFormHttpMessageConverter.class, source)); if (romePresent) { messageConverters.add(createConverterDefinition(AtomFeedHttpMessageConverter.class, source)); messageConverters.add(createConverterDefinition(RssChannelHttpMessageConverter.class, source)); } // 新增json轉xml轉換器 if (jackson2XmlPresent) { Class<?> type = MappingJackson2XmlHttpMessageConverter.class; RootBeanDefinition jacksonConverterDef = createConverterDefinition(type, source); GenericBeanDefinition jacksonFactoryDef = createObjectMapperFactoryDefinition(source); jacksonFactoryDef.getPropertyValues().add("createXmlMapper", true); jacksonConverterDef.getConstructorArgumentValues().addIndexedArgumentValue(0, jacksonFactoryDef); messageConverters.add(jacksonConverterDef); } // 新增物件xml轉換器 else if (jaxb2Present) { messageConverters.add(createConverterDefinition(Jaxb2RootElementHttpMessageConverter.class, source)); } // 新增Jackson json轉換器 if (jackson2Present) { Class<?> type = MappingJackson2HttpMessageConverter.class; RootBeanDefinition jacksonConverterDef = createConverterDefinition(type, source); GenericBeanDefinition jacksonFactoryDef = createObjectMapperFactoryDefinition(source); jacksonConverterDef.getConstructorArgumentValues().addIndexedArgumentValue(0, jacksonFactoryDef); messageConverters.add(jacksonConverterDef); } // 新增Gson json轉換器 else if (gsonPresent) { messageConverters.add(createConverterDefinition(GsonHttpMessageConverter.class, source)); } } return messageConverters; }
進入到這個方法org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter#AllEncompassingFormHttpMessageConverter
public AllEncompassingFormHttpMessageConverter() { // 新增預設xml和json真支援轉換器 addPartConverter(new SourceHttpMessageConverter<Source>()); if (jaxb2Present && !jackson2XmlPresent) { addPartConverter(new Jaxb2RootElementHttpMessageConverter()); } if (jackson2Present) { addPartConverter(new MappingJackson2HttpMessageConverter()); } else if (gsonPresent) { addPartConverter(new GsonHttpMessageConverter()); } if (jackson2XmlPresent) { addPartConverter(new MappingJackson2XmlHttpMessageConverter()); } }
往上返回到這個方法org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#getArgumentResolvers
private ManagedList<?> getArgumentResolvers(Element element, ParserContext context) { Element resolversElement = DomUtils.getChildElementByTagName(element, "argument-resolvers"); if (resolversElement != null) { ManagedList<Object> resolvers = extractBeanSubElements(resolversElement, context); // -> return wrapLegacyResolvers(resolvers, context); } return null; }
進入到這個方法org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#wrapLegacyResolvers
private ManagedList<Object> wrapLegacyResolvers(List<Object> list, ParserContext context) { ManagedList<Object> result = new ManagedList<Object>(); for (Object object : list) { if (object instanceof BeanDefinitionHolder) { BeanDefinitionHolder beanDef = (BeanDefinitionHolder) object; String className = beanDef.getBeanDefinition().getBeanClassName(); Class<?> clazz = ClassUtils.resolveClassName(className, context.getReaderContext().getBeanClassLoader()); if (WebArgumentResolver.class.isAssignableFrom(clazz)) { // 新增ServletWebArgumentResolverAdapter 引數解析器介面卡 RootBeanDefinition adapter = new RootBeanDefinition(ServletWebArgumentResolverAdapter.class); adapter.getConstructorArgumentValues().addIndexedArgumentValue(0, beanDef); result.add(new BeanDefinitionHolder(adapter, beanDef.getBeanName() + "Adapter")); continue; } } result.add(object); } return result; }
返回到這個方法org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser#parse這一行
// 獲取返回值handler -> ManagedList<?> returnValueHandlers = getReturnValueHandlers(element, context);
下次繼續
說到最後
本次原始碼解析僅代表個人觀點,僅供參