說在前面java
本次主要介紹springmvc配置解析。關注「天河聊架構」微信公衆號有更多精彩。web
springmvc配置解析spring
@EnableWebMvc這個註解幹了什麼,初始化RequestMappingHandlerAdapterjson
進入到這個方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#requestMappingHandlerAdapter緩存
@Bean public RequestMappingHandlerAdapter requestMappingHandlerAdapter() { // 建立requestMappingHandlerAdapter -》 RequestMappingHandlerAdapter adapter = createRequestMappingHandlerAdapter(); // 設置媒體類型管理器 -》 adapter.setContentNegotiationManager(mvcContentNegotiationManager()); // 添加消息轉換器 -》 adapter.setMessageConverters(getMessageConverters()); // 設置配置綁定器 -》 adapter.setWebBindingInitializer(getConfigurableWebBindingInitializer()); // 設置參數解析器 -》 adapter.setCustomArgumentResolvers(getArgumentResolvers()); // 設置returnHandlers adapter.setCustomReturnValueHandlers(getReturnValueHandlers()); if (jackson2Present) { // 設置JsonViewRequestBodyAdvice、JsonViewResponseBodyAdvice adapter.setRequestBodyAdvice( Collections.<RequestBodyAdvice>singletonList(new JsonViewRequestBodyAdvice())); adapter.setResponseBodyAdvice( Collections.<ResponseBodyAdvice<?>>singletonList(new JsonViewResponseBodyAdvice())); } // 建立異步支持配置器 AsyncSupportConfigurer configurer = new AsyncSupportConfigurer(); // 配置異步支持配置器 configureAsyncSupport(configurer); if (configurer.getTaskExecutor() != null) { // 設置任務執行器 adapter.setTaskExecutor(configurer.getTaskExecutor()); } if (configurer.getTimeout() != null) { // 設置超時時間 adapter.setAsyncRequestTimeout(configurer.getTimeout()); } // 設置返回值攔截器 adapter.setCallableInterceptors(configurer.getCallableInterceptors()); // 設置延遲結果攔截器 adapter.setDeferredResultInterceptors(configurer.getDeferredResultInterceptors()); return adapter; }
進入到這個方法org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#RequestMappingHandlerAdapter微信
public RequestMappingHandlerAdapter() { // 建立StringHttpMessageConverter StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(); stringHttpMessageConverter.setWriteAcceptCharset(false); // see SPR-7316 // 添加轉換器 this.messageConverters = new ArrayList<HttpMessageConverter<?>>(4); this.messageConverters.add(new ByteArrayHttpMessageConverter()); this.messageConverters.add(stringHttpMessageConverter); this.messageConverters.add(new SourceHttpMessageConverter<Source>()); // 添加xml和json轉換器 -》 this.messageConverters.add(new AllEncompassingFormHttpMessageConverter()); }
進入到這個方法org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter#AllEncompassingFormHttpMessageConvertercookie
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.annotation.WebMvcConfigurationSupport#mvcContentNegotiationManagersession
@Bean public ContentNegotiationManager mvcContentNegotiationManager() { if (this.contentNegotiationManager == null) { // 初始化媒體類型管理器 ContentNegotiationConfigurer configurer = new ContentNegotiationConfigurer(this.servletContext); // 設置默認類型 -》 configurer.mediaTypes(getDefaultMediaTypes()); // 配置媒體類型管理器 -》 configureContentNegotiation(configurer); // 構建媒體類型管理器 -》 this.contentNegotiationManager = configurer.buildContentNegotiationManager(); } return this.contentNegotiationManager; }
進入到這個方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#getDefaultMediaTypes架構
protected Map<String, MediaType> getDefaultMediaTypes() { Map<String, MediaType> map = new HashMap<String, MediaType>(4); if (romePresent) { map.put("atom", MediaType.APPLICATION_ATOM_XML); map.put("rss", MediaType.APPLICATION_RSS_XML); } if (jaxb2Present || jackson2XmlPresent) { map.put("xml", MediaType.APPLICATION_XML); } if (jackson2Present || gsonPresent) { map.put("json", MediaType.APPLICATION_JSON); } return map; }
往上返回到這個方法org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration#configureContentNegotiationmvc
@Override protected void configureContentNegotiation(ContentNegotiationConfigurer configurer) { this.configurers.configureContentNegotiation(configurer); }
往上返回到這個方法org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer#buildContentNegotiationManager
protected ContentNegotiationManager buildContentNegotiationManager() { // 添加媒體類型 this.factory.addMediaTypes(this.mediaTypes); // 等待ContentNegotiationManagerFactoryBean初始化配置 this.factory.afterPropertiesSet(); return this.factory.getObject(); }
往上返回到這個方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#getMessageConverters
protected final List<HttpMessageConverter<?>> getMessageConverters() { if (this.messageConverters == null) { this.messageConverters = new ArrayList<HttpMessageConverter<?>>(); // 配置消息轉換器 -》 configureMessageConverters(this.messageConverters); if (this.messageConverters.isEmpty()) { // 添加默認http消息轉換器 -》 addDefaultHttpMessageConverters(this.messageConverters); } // 擴展消息轉換器 extendMessageConverters(this.messageConverters); } return this.messageConverters; }
進入到這個方法org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration#configureMessageConverters
@Override protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) { this.configurers.configureMessageConverters(converters); }
往上返回到這個方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#addDefaultHttpMessageConverters
protected final void addDefaultHttpMessageConverters(List<HttpMessageConverter<?>> messageConverters) { // 建立StringHttpMessageConverter StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(); stringConverter.setWriteAcceptCharset(false); messageConverters.add(new ByteArrayHttpMessageConverter()); messageConverters.add(stringConverter); messageConverters.add(new ResourceHttpMessageConverter()); messageConverters.add(new SourceHttpMessageConverter<Source>()); // -》 messageConverters.add(new AllEncompassingFormHttpMessageConverter()); if (romePresent) { messageConverters.add(new AtomFeedHttpMessageConverter()); messageConverters.add(new RssChannelHttpMessageConverter()); } // Jackson2Xml 轉換器 if (jackson2XmlPresent) { messageConverters.add(new MappingJackson2XmlHttpMessageConverter( Jackson2ObjectMapperBuilder.xml().applicationContext(this.applicationContext).build())); } else if (jaxb2Present) { // Jaxb2RootElement 轉換器 messageConverters.add(new Jaxb2RootElementHttpMessageConverter()); } // Jackson 轉換器 if (jackson2Present) { messageConverters.add(new MappingJackson2HttpMessageConverter( Jackson2ObjectMapperBuilder.json().applicationContext(this.applicationContext).build())); } else if (gsonPresent) { // gson 轉換器 messageConverters.add(new GsonHttpMessageConverter()); } }
進入到這個方法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.annotation.WebMvcConfigurationSupport#getConfigurableWebBindingInitializer
protected ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer() { // 初始化配置綁定器 ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer(); // 設置轉換服務 -》 initializer.setConversionService(mvcConversionService()); // 設置校驗器-》 initializer.setValidator(mvcValidator()); // 設置MessageCodesResolver initializer.setMessageCodesResolver(getMessageCodesResolver()); return initializer; }
進入到這個方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#mvcConversionService
@Bean public FormattingConversionService mvcConversionService() { // 初始化默認轉換服務 FormattingConversionService conversionService = new DefaultFormattingConversionService(); // 添加格式化器 -》 addFormatters(conversionService); return conversionService; }
這裏前面介紹過了。
往上返回到這個方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#mvcValidator
@Bean public Validator mvcValidator() { // 獲取驗證器 Validator validator = getValidator(); if (validator == null) { if (ClassUtils.isPresent("javax.validation.Validator", getClass().getClassLoader())) { Class<?> clazz; try { String className = "org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean"; clazz = ClassUtils.forName(className, WebMvcConfigurationSupport.class.getClassLoader()); } catch (ClassNotFoundException ex) { throw new BeanInitializationException("Could not find default validator class", ex); } catch (LinkageError ex) { throw new BeanInitializationException("Could not load default validator class", ex); } validator = (Validator) BeanUtils.instantiateClass(clazz); } else { validator = new NoOpValidator(); } } return validator; }
往上返回到這個方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#getArgumentResolvers
protected final List<HandlerMethodArgumentResolver> getArgumentResolvers() { if (this.argumentResolvers == null) { this.argumentResolvers = new ArrayList<HandlerMethodArgumentResolver>(); addArgumentResolvers(this.argumentResolvers); } return this.argumentResolvers; }
進入到這個方法org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration#addArgumentResolvers
@Override protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { this.configurers.addArgumentResolvers(argumentResolvers); }
往上返回到這個方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#getReturnValueHandlers
protected final List<HandlerMethodReturnValueHandler> getReturnValueHandlers() { if (this.returnValueHandlers == null) { this.returnValueHandlers = new ArrayList<HandlerMethodReturnValueHandler>(); addReturnValueHandlers(this.returnValueHandlers); } return this.returnValueHandlers; }
進入到這個方法org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration#addReturnValueHandlers
@Override protected void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) { this.configurers.addReturnValueHandlers(returnValueHandlers); }
往上返回到這個方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#requestMappingHandlerAdapter
進入到這個方法org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#afterPropertiesSet
@Override public void afterPropertiesSet() { // Do this first, it may add ResponseBody advice beans 初始化ControllerAdvice緩存-》 initControllerAdviceCache(); if (this.argumentResolvers == null) { // 獲取默認的方法參數解析器 -》 List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers(); this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers); } if (this.initBinderArgumentResolvers == null) { // 獲取默認的@InitBinder參數綁定解析器 -》 List<HandlerMethodArgumentResolver> resolvers = getDefaultInitBinderArgumentResolvers(); this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers); } if (this.returnValueHandlers == null) { // 解析默認的返回值handler -》 List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers(); this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers); } }
往上返回到這個方法org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#initControllerAdviceCache
private void initControllerAdviceCache() { if (getApplicationContext() == null) { return; } if (logger.isInfoEnabled()) { logger.info("Looking for @ControllerAdvice: " + getApplicationContext()); } // 從beanFactory中獲取參數@ControllerAdvice的controller List<ControllerAdviceBean> beans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext()); AnnotationAwareOrderComparator.sort(beans); List<Object> requestResponseBodyAdviceBeans = new ArrayList<Object>(); for (ControllerAdviceBean bean : beans) { // 從controller中獲取有@RequestMapping、@ModelAttribute註解的方法 Set<Method> attrMethods = MethodIntrospector.selectMethods(bean.getBeanType(), MODEL_ATTRIBUTE_METHODS); if (!attrMethods.isEmpty()) { this.modelAttributeAdviceCache.put(bean, attrMethods); if (logger.isInfoEnabled()) { logger.info("Detected @ModelAttribute methods in " + bean); } } // 查找controller中有@InitBinder註解的方法 Set<Method> binderMethods = MethodIntrospector.selectMethods(bean.getBeanType(), INIT_BINDER_METHODS); if (!binderMethods.isEmpty()) { this.initBinderAdviceCache.put(bean, binderMethods); if (logger.isInfoEnabled()) { logger.info("Detected @InitBinder methods in " + bean); } } if (RequestBodyAdvice.class.isAssignableFrom(bean.getBeanType())) { requestResponseBodyAdviceBeans.add(bean); if (logger.isInfoEnabled()) { logger.info("Detected RequestBodyAdvice bean in " + bean); } } if (ResponseBodyAdvice.class.isAssignableFrom(bean.getBeanType())) { requestResponseBodyAdviceBeans.add(bean); if (logger.isInfoEnabled()) { logger.info("Detected ResponseBodyAdvice bean in " + bean); } } } if (!requestResponseBodyAdviceBeans.isEmpty()) { this.requestResponseBodyAdvice.addAll(0, requestResponseBodyAdviceBeans); } }
往上返回到這個方法org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getDefaultArgumentResolvers
private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() { List<HandlerMethodArgumentResolver> resolvers = new ArrayList<HandlerMethodArgumentResolver>(); // Annotation-based argument resolution // 基於@RequestParam的參數解析器 resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false)); // 基於@RequestParam map參數解析器 resolvers.add(new RequestParamMapMethodArgumentResolver()); // 基於@PathVariable的參數解析器 resolvers.add(new PathVariableMethodArgumentResolver()); // 基於@PathVariable map的參數解析器 resolvers.add(new PathVariableMapMethodArgumentResolver()); // 基於@MatrixVariable 矩陣參數解析器 resolvers.add(new MatrixVariableMethodArgumentResolver()); // 基於@MatrixVariable 矩陣map參數解析器 resolvers.add(new MatrixVariableMapMethodArgumentResolver()); // 基於從model解析參數的參數解析器 resolvers.add(new ServletModelAttributeMethodProcessor(false)); // 基於@RequestBody、@ResponseBody的參數解析器 resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice)); // 基於@RequestParam 參數解析器 resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters(), this.requestResponseBodyAdvice)); // 基於@RequestHeader 參數解析器 resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory())); // 基於@RequestHeader map參數解析器 resolvers.add(new RequestHeaderMapMethodArgumentResolver()); // 基於從cookie中解析參數的參數解析器 resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory())); // 基於@Value 表達式參數解析器 resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory())); // 基於@SessionAttribute 參數解析器 resolvers.add(new SessionAttributeMethodArgumentResolver()); // 基於@RequestAttribute 參數解析器 resolvers.add(new RequestAttributeMethodArgumentResolver()); // Type-based argument resolution // 基於servletRequest的參數解析器 resolvers.add(new ServletRequestMethodArgumentResolver()); // 基於servletResponse的參數解析器 resolvers.add(new ServletResponseMethodArgumentResolver()); // 基於httpEntity參數解析器 resolvers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice)); // 基於重定向參數綁定解析器 resolvers.add(new RedirectAttributesMethodArgumentResolver()); // 基於從model中解析參數的參數解析器 resolvers.add(new ModelMethodProcessor()); // 基於map的參數解析器 resolvers.add(new MapMethodProcessor()); // 錯誤方法參數解析器 resolvers.add(new ErrorsMethodArgumentResolver()); // 基於session狀態方法參數解析器 resolvers.add(new SessionStatusMethodArgumentResolver()); // 基於url參數解析器 resolvers.add(new UriComponentsBuilderMethodArgumentResolver()); // Custom arguments 自定義參數解析器 if (getCustomArgumentResolvers() != null) { resolvers.addAll(getCustomArgumentResolvers()); } // Catch-all // 基於@RequestParam參數解析器,用默認值 resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true)); // 基於servlet model中解析參數的參數解析器,使用默認值 resolvers.add(new ServletModelAttributeMethodProcessor(true)); return resolvers; }
往上返回到這個方法org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getDefaultInitBinderArgumentResolvers
private List<HandlerMethodArgumentResolver> getDefaultInitBinderArgumentResolvers() { List<HandlerMethodArgumentResolver> resolvers = new ArrayList<HandlerMethodArgumentResolver>(); // Annotation-based argument resolution // 基於@RequestParam的參數解析器 resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false)); // 基於@RequestParam map的參數解析器 resolvers.add(new RequestParamMapMethodArgumentResolver()); // 基於@PathVariable 的參數解析器 resolvers.add(new PathVariableMethodArgumentResolver()); // 基於@PathVariable map的參數解析器 resolvers.add(new PathVariableMapMethodArgumentResolver()); // 基於@MatrixVariable 矩陣參數解析器 resolvers.add(new MatrixVariableMethodArgumentResolver()); // 基於@MatrixVariable map矩陣參數解析器 resolvers.add(new MatrixVariableMapMethodArgumentResolver()); // 基於@Value 表達式參數解析器 resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory())); // 基於@SessionAttribute參數解析器 resolvers.add(new SessionAttributeMethodArgumentResolver()); // 基於@RequestAttribute 參數解析器 resolvers.add(new RequestAttributeMethodArgumentResolver()); // Type-based argument resolution // 基於servletRequest參數解析器 resolvers.add(new ServletRequestMethodArgumentResolver()); // 基於servletResponse參數解析器 resolvers.add(new ServletResponseMethodArgumentResolver()); // Custom arguments if (getCustomArgumentResolvers() != null) { resolvers.addAll(getCustomArgumentResolvers()); } // Catch-all // 基於@RequestParam 參數解析器,使用默認值 resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true)); return resolvers; }
往上返回到這個方法org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getDefaultReturnValueHandlers
private List<HandlerMethodReturnValueHandler> getDefaultReturnValueHandlers() { List<HandlerMethodReturnValueHandler> handlers = new ArrayList<HandlerMethodReturnValueHandler>(); // Single-purpose return value types // 方法返回值是ModelAndView的返回值解析器 handlers.add(new ModelAndViewMethodReturnValueHandler()); // 方法返回值是model的返回值解析器 handlers.add(new ModelMethodProcessor()); // 方法是返回值是view的返回值解析器 handlers.add(new ViewMethodReturnValueHandler()); // 方法返回值是responseEntity的返回值解析器 handlers.add(new ResponseBodyEmitterReturnValueHandler(getMessageConverters())); // 方法返回值是流的返回值解析器 handlers.add(new StreamingResponseBodyReturnValueHandler()); // 方法返回值是httpEntity的方法返回值解析器 handlers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.contentNegotiationManager, this.requestResponseBodyAdvice)); // 方法返回值是httpHeaders的方法返回值解析器 handlers.add(new HttpHeadersReturnValueHandler()); // 方法返回值是callable的方法返回值解析器 handlers.add(new CallableMethodReturnValueHandler()); // 方法返回值是DeferredResult的方法返回值解析器 handlers.add(new DeferredResultMethodReturnValueHandler()); // 方法返回值是WebAsyncTask的方法返回值解析器 handlers.add(new AsyncTaskMethodReturnValueHandler(this.beanFactory)); // Annotation-based return value types // 方法上有@ModelAttribute註解的返回值解析器 handlers.add(new ModelAttributeMethodProcessor(false)); // 基於@RequestBody、@ResponseBody的返回值解析器 handlers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.contentNegotiationManager, this.requestResponseBodyAdvice)); // Multi-purpose return value types // 基於視圖名字的返回值解析器 handlers.add(new ViewNameMethodReturnValueHandler()); // 基於map的返回值解析器 handlers.add(new MapMethodProcessor()); // Custom return value types 自定義返回值解析器 if (getCustomReturnValueHandlers() != null) { handlers.addAll(getCustomReturnValueHandlers()); } // Catch-all // 基於modelAndView的返回值解析器 if (!CollectionUtils.isEmpty(getModelAndViewResolvers())) { handlers.add(new ModelAndViewResolverMethodReturnValueHandler(getModelAndViewResolvers())); } else { // 方法上有@ModelAttribute註解的返回值解析器,使用默認值 handlers.add(new ModelAttributeMethodProcessor(true)); } return handlers; }
往上返回到這個方法org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#afterPropertiesSet
說到最後
本次源碼解析僅表明我的觀點,僅供參考。