在SpringMVC自动装配核心类之WebMvcAutoConfiguration
内部实例化EnableWebMvcConfiguration
过程中会触发其父类WebMvcConfigurationSupport
内部初始化HandlerExceptionResolver
。
1.WebMvcConfigurationSupport
public class WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware {@Beanpublic HandlerExceptionResolver handlerExceptionResolver(@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager) {List<HandlerExceptionResolver> exceptionResolvers = new ArrayList<>();configureHandlerExceptionResolvers(exceptionResolvers);if (exceptionResolvers.isEmpty()) {addDefaultHandlerExceptionResolvers(exceptionResolvers, contentNegotiationManager);}extendHandlerExceptionResolvers(exceptionResolvers);HandlerExceptionResolverComposite composite = new HandlerExceptionResolverComposite();composite.setOrder(0);composite.setExceptionResolvers(exceptionResolvers);return composite;}protected final void addDefaultHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers,ContentNegotiationManager manager) {//得到 ExceptionHandlerExceptionResolverExceptionHandlerExceptionResolver exceptionHandlerResolver = createExceptionHandlerExceptionResolver();...exceptionHandlerResolver.afterPropertiesSet();exceptionResolvers.add(exceptionHandlerResolver);ResponseStatusExceptionResolver responseStatusResolver = new ResponseStatusExceptionResolver();responseStatusResolver.setMessageSource(this.applicationContext);exceptionResolvers.add(responseStatusResolver);exceptionResolvers.add(new DefaultHandlerExceptionResolver());}
}
最终返回HandlerExceptionResolver类型为HandlerExceptionResolverComposite
。并且其resolvers
属性包含了三种元素分别为ExceptionHandlerExceptionResolver
、ResponseStatusExceptionResolver
、DefaultHandlerExceptionResolver
。
不管应用中是否显式指定全局异常拦截注解@ControllerAdvice。SpringMVC都会执行初始化异常处理解析器【HandlerExceptionResolver】的逻辑,唯一的区别就是ExceptionHandlerExceptionResolver内部其属性exceptionHandlerAdviceCache是否存在元素,元素存在与否表明了应用中是否显式指定全局异常拦截注解@ControllerAdvice。
1.2.ExceptionHandlerExceptionResolver
ControllerAdviceBean
是对全局异常Handler的抽象,ExceptionHandlerMethodResolver
是对Handler核心方法的抽象。
最终目的是建立并在属性exceptionHandlerAdviceCache
缓存 ControllerAdviceBean & ExceptionHandlerMethodResolver 的对应关系,方便后续直接使用。
public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExceptionResolverimplements ApplicationContextAware, InitializingBean {Map<ControllerAdviceBean, ExceptionHandlerMethodResolver> exceptionHandlerAdviceCache = new LinkedHashMap<>();public void afterPropertiesSet() {initExceptionHandlerAdviceCache();...}private void initExceptionHandlerAdviceCache() {// 返回 @ControllerAdvice 注解的类List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());for (ControllerAdviceBean adviceBean : adviceBeans) {// 全局异常拦截handler:其实就是指@ControllerAdvice注解的类Class<?> beanType = adviceBean.getBeanType();// 封装全局异常拦截handler相关属性:核心是拦截handler中的方法ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(beanType);if (resolver