說在前面web
本次主要介紹springmvc配置解析。關注「天河聊架構」微信公衆號有更多精彩。spring
springmvc配置解析緩存
@EnableWebMvc這個註解幹了什麼,初始化HandlerExceptionResolver微信
進入到這個方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#handlerExceptionResolversession
@Bean public HandlerExceptionResolver handlerExceptionResolver() { // 建立HandlerExceptionResolver List<HandlerExceptionResolver> exceptionResolvers = new ArrayList<HandlerExceptionResolver>(); configureHandlerExceptionResolvers(exceptionResolvers); if (exceptionResolvers.isEmpty()) { // 添加默認的HandlerExceptionResolvers -》 addDefaultHandlerExceptionResolvers(exceptionResolvers); } extendHandlerExceptionResolvers(exceptionResolvers); HandlerExceptionResolverComposite composite = new HandlerExceptionResolverComposite(); composite.setOrder(0); composite.setExceptionResolvers(exceptionResolvers); return composite; }
進入到這個方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#addDefaultHandlerExceptionResolvers架構
protected final void addDefaultHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) { // 建立ExceptionHandlerExceptionResolver ExceptionHandlerExceptionResolver exceptionHandlerResolver = createExceptionHandlerExceptionResolver(); // 設置媒體類型管理器 -》 exceptionHandlerResolver.setContentNegotiationManager(mvcContentNegotiationManager()); // 設置消息轉換器 -》 exceptionHandlerResolver.setMessageConverters(getMessageConverters()); // 設置參數解析器 exceptionHandlerResolver.setCustomArgumentResolvers(getArgumentResolvers()); // 設置returnHandlers -》 exceptionHandlerResolver.setCustomReturnValueHandlers(getReturnValueHandlers()); if (jackson2Present) { // 設置JsonViewResponseBodyAdvice exceptionHandlerResolver.setResponseBodyAdvice( Collections.<ResponseBodyAdvice<?>>singletonList(new JsonViewResponseBodyAdvice())); } exceptionHandlerResolver.setApplicationContext(this.applicationContext); // exceptionHandlerResolver 配置加載 -》 exceptionHandlerResolver.afterPropertiesSet(); exceptionResolvers.add(exceptionHandlerResolver); // 建立ResponseStatusExceptionResolver ResponseStatusExceptionResolver responseStatusResolver = new ResponseStatusExceptionResolver(); responseStatusResolver.setMessageSource(this.applicationContext); exceptionResolvers.add(responseStatusResolver); // 建立DefaultHandlerExceptionResolver exceptionResolvers.add(new DefaultHandlerExceptionResolver()); }
進入到這個方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#mvcContentNegotiationManagermvc
@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; }
這裏前面介紹過了。app
往上返回到這個方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#getMessageConverterside
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; }
這裏前面介紹過了。ui
往上返回到這個方法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.mvc.method.annotation.ExceptionHandlerExceptionResolver#afterPropertiesSet
@Override public void afterPropertiesSet() { // Do this first, it may add ResponseBodyAdvice beans 初始化異常handler通知緩存 -》 initExceptionHandlerAdviceCache(); if (this.argumentResolvers == null) { // 獲取默認的參數解析器-》 List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers(); this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers); } if (this.returnValueHandlers == null) { // 獲取默認的ReturnValueHandlers -》 List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers(); this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers); } }
進入到這個方法org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#initExceptionHandlerAdviceCache
private void initExceptionHandlerAdviceCache() { if (getApplicationContext() == null) { return; } if (logger.isDebugEnabled()) { logger.debug("Looking for exception mappings: " + getApplicationContext()); } // 查找@ControllerAdvice註解的controller -》 List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext()); AnnotationAwareOrderComparator.sort(adviceBeans); for (ControllerAdviceBean adviceBean : adviceBeans) { ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(adviceBean.getBeanType()); if (resolver.hasExceptionMappings()) { this.exceptionHandlerAdviceCache.put(adviceBean, resolver); if (logger.isInfoEnabled()) { logger.info("Detected @ExceptionHandler methods in " + adviceBean); } } if (ResponseBodyAdvice.class.isAssignableFrom(adviceBean.getBeanType())) { this.responseBodyAdvice.add(adviceBean); if (logger.isInfoEnabled()) { logger.info("Detected ResponseBodyAdvice implementation in " + adviceBean); } } } }
進入到這個方法org.springframework.web.method.ControllerAdviceBean#findAnnotatedBeans
public static List<ControllerAdviceBean> findAnnotatedBeans(ApplicationContext applicationContext) { List<ControllerAdviceBean> beans = new ArrayList<ControllerAdviceBean>(); for (String name : BeanFactoryUtils.beanNamesForTypeIncludingAncestors(applicationContext, Object.class)) { if (applicationContext.findAnnotationOnBean(name, ControllerAdvice.class) != null) { beans.add(new ControllerAdviceBean(name, applicationContext)); } } return beans; }
往上返回到這個方法org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#getDefaultArgumentResolvers
protected List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() { List<HandlerMethodArgumentResolver> resolvers = new ArrayList<HandlerMethodArgumentResolver>(); // Annotation-based argument resolution // 從session中解析參數解析器@SessionAttribute resolvers.add(new SessionAttributeMethodArgumentResolver()); // 從request中解析參數解析器@RequestAttribute resolvers.add(new RequestAttributeMethodArgumentResolver()); // Type-based argument resolution // 基於servletRequets的參數解析器 resolvers.add(new ServletRequestMethodArgumentResolver()); // 基於servletResponse的參數解析器 resolvers.add(new ServletResponseMethodArgumentResolver()); // 重定向綁定參數解析器 resolvers.add(new RedirectAttributesMethodArgumentResolver()); // 從model中解析參數解析器 resolvers.add(new ModelMethodProcessor()); // Custom arguments 自定義參數解析器 if (getCustomArgumentResolvers() != null) { resolvers.addAll(getCustomArgumentResolvers()); } return resolvers; }
往上返回到這個方法org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#getDefaultReturnValueHandlers
protected 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()); // 基於HttpEntity的返回值解析器 handlers.add(new HttpEntityMethodProcessor( getMessageConverters(), this.contentNegotiationManager, this.responseBodyAdvice)); // Annotation-based return value types // 基於@ModelAttribute屬性方法的返回值解析器 handlers.add(new ModelAttributeMethodProcessor(false)); // 基於@RequestBody和@ResponseBody註解方法的參數解析器 handlers.add(new RequestResponseBodyMethodProcessor( getMessageConverters(), this.contentNegotiationManager, this.responseBodyAdvice)); // 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 // 基於@ModelAttribute註解方法的解析器 handlers.add(new ModelAttributeMethodProcessor(true)); return handlers; }
往上返回到這個方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#handlerExceptionResolver
說到最後
本次源碼解析僅表明我的觀點,僅供參考。