说在前面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
说到最后
本次源码解析仅表明我的观点,仅供参考。