1.问题

在进行日志记录的时候,使用了filter过滤器。想当然的认为在过滤器中捕捉到所有异常,然后记录日志。结果是发生异常后,过滤器中无法捕捉到,异常已经被其它程序捕捉。到底是为什么了,于是本人稍微探究了一下这个过程;

2.简介

2.1.http请求的调用过程

http请求调用过程

2.2.全局异常处理器结构

全局异常处理器结构

2.3.运行过程说明

  • 项目启动,spring加载全局异常处理器
  • http请求,被filter拦截,调用filterChain.dofilter(),经过一系统的过滤器链。最后达到spring的DispatcherServlet;
  • DispatcherServlet调用对应的handler(Controller)处理业务逻辑;
  • 没有异常则返回到过滤器链,执行filterChain.dofilter()后面的代码;
  • 如果发生异常,则调用异常处理器进行处理异常;
    • 调用DefaultErrorAttributes,把异常存放到HttpServletRequest和WebRequest中;
    • 调用HandlerExceptionResolverComposite。实际上它只是其它异常处理器的组合,它会按顺序交给其它异常处理器处理,直到能处理当前异常;
      • 调用ExceptionHandlerExceptionResolver,获取用户配置的全局异常处理器处理异常;
      • 调用ResponseStatusExceptionResolver,处理ResponseStatusException和@ResponseStatus标注和自定义异常;
      • 调用DefaultHandlerExceptionResolver,处理常见异常,返回http异常码;
  • 如果异常已经被处理,则正常返回。返回到过滤器链,执行filterChain.dofilter()后面的代码;
  • 如果异常不能被处理,则抛出异常。返回到过滤器链,执行catch里面的代码;

3.运行过程源码

3.1.项目启动

A.WebMvcConfigurationSupport初始化全局异常处理器

@Bean
public HandlerExceptionResolver handlerExceptionResolver() {
	List<HandlerExceptionResolver> exceptionResolvers = new ArrayList<>();
	//**默认什么也没做
	configureHandlerExceptionResolvers(exceptionResolvers);
	//**获取实际的异常处理器
	//**按顺序创建ExceptionHandlerExceptionResolver,ResponseStatusExceptionResolver和DefaultHandlerExceptionResolver
	if (exceptionResolvers.isEmpty()) {
		addDefaultHandlerExceptionResolvers(exceptionResolvers);
	}
	extendHandlerExceptionResolvers(exceptionResolvers);
	//**创建组合的异常处理器,并set实际的异常处理器
	HandlerExceptionResolverComposite composite = new HandlerExceptionResolverComposite();
	composite.setOrder(0);
	composite.setExceptionResolvers(exceptionResolvers);
	return composite;
}

3.2.DispatcherServlet处理http请求

A.接收请求

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
	try {
	    ...省略...
		//**调用Controller
		mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
	}
	catch (Exception ex) {  //**发生异常,赋值
		dispatchException = ex;
	}
	...省略...
	//**处理结果
	processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}

B.处理结果

private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
			@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
			@Nullable Exception exception) throws Exception {
    //**发生异常
	if (exception != null) {
	    //**ModelAndViewDefiningException处理
		if (exception instanceof ModelAndViewDefiningException) {
			logger.debug("ModelAndViewDefiningException encountered", exception);
			mv = ((ModelAndViewDefiningException) exception).getModelAndView();
		}
		else { //**其它异常调用processHandlerException方法处理,返回null表示不能处理
			Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
			mv = processHandlerException(request, response, handler, exception);
			errorView = (mv != null);
		}
	}
    ...省略...
}

C.处理异常

protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response,
			@Nullable Object handler, Exception ex) throws Exception {
	//**调用所有的异常处理器处理异常,异常处理器返回不为null表示处理完毕
	if (this.handlerExceptionResolvers != null) {
		for (HandlerExceptionResolver resolver : this.handlerExceptionResolvers) {
			exMv = resolver.resolveException(request, response, handler, ex);
			if (exMv != null) {
				break;
			}
		}
	}
	if (exMv != null) {
	    //**异常处理完毕,把异常存放到HttpServletRequest中
		if (exMv.isEmpty()) {
			request.setAttribute(EXCEPTION_ATTRIBUTE, ex);
			return null;
		}
		...省略...
	}
    
    //**无法处理则抛出异常
	throw ex;
}

4.全局异常处理器源码

4.1.HandlerExceptionResolver接口

提供了一个resolveException方法。处理异常,如果处理不了则返回null;

public interface HandlerExceptionResolver {
    //**处理异常,如果处理不了返回null
	ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex);
}

4.2.DefaultErrorAttributes异常处理器

把异常信息保存到HttpServletRequest和WebRequest中,并可以根据WebRequest获取异常信息;

public interface ErrorAttributes {
    //**获取异常信息
	Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace);
    //**获取异常
	Throwable getError(WebRequest webRequest);
}

public class DefaultErrorAttributes implements ErrorAttributes, HandlerExceptionResolver, Ordered {

    //**把异常信息保存到HttpServletRequest中
	@Override
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
			Exception ex) {
		storeErrorAttributes(request, ex);
		return null;
	}
	private void storeErrorAttributes(HttpServletRequest request, Exception ex) {
		request.setAttribute(ERROR_ATTRIBUTE, ex);
	}
}

4.3.HandlerExceptionResolverComposite异常处理器

组合模式,组合实际的异常处理器。把异常按顺序交给其它异常处理器处理,直到能处理当前异常;

public class HandlerExceptionResolverComposite implements HandlerExceptionResolver, Ordered {
    //**引用实际的异常处理器
	private List<HandlerExceptionResolver> resolvers;

    //**把异常按顺序交给其它异常处理器处理,直到能处理当前异常
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponseresponse, Object handler, Exception ex) {
		if (this.resolvers != null) {
			for (HandlerExceptionResolver handlerExceptionResolver : this.resolvers) {
				ModelAndView mav = handlerExceptionResolver.resolveException(request, response, handler, ex);
				if (mav != null) {
					return mav;
				}
			}
		}
		return null;
	}
}

4.4.AbstractHandlerExceptionResolver异常处理器

对HandlerExceptionResolver接口进行扩展,支持设置支持的handler bean名称/class对象;

public abstract class AbstractHandlerExceptionResolver implements HandlerExceptionResolver, Ordered {
    //**支持的handler bean名称,一般都是Controller
	private Set<?> mappedHandlers;
	//**支持的handler类对象,一般都是Controller
	private Class<?>[] mappedHandlerClasses;
	
	//**设置支持的handler bean名称和handler类对象

    //**处理异常,判断是否支持当前的handler,如果支持则处理异常
	public ModelAndView resolveException(
			HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) {

		if (shouldApplyTo(request, handler)) {
			prepareResponse(ex, response);
			ModelAndView result = doResolveException(request, response, handler, ex);
            ...
			return result;
		}
		else {
			return null;
		}
	}

    //**判断是否支持当前的handler
	protected boolean shouldApplyTo(HttpServletRequest request, @Nullable Object handler) {
		if (handler != null) {
			if (this.mappedHandlers != null && this.mappedHandlers.contains(handler)) {
				return true;
			}
			if (this.mappedHandlerClasses != null) {
				for (Class<?> handlerClass : this.mappedHandlerClasses) {
					if (handlerClass.isInstance(handler)) {
						return true;
					}
				}
			}
		}
		// Else only apply if there are no explicit handler mappings.
		return (this.mappedHandlers == null && this.mappedHandlerClasses == null);
	}

    //**新的异常处理方法
	protected abstract ModelAndView doResolveException(
			HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex);
}

4.5.SimpleMappingExceptionResolver异常处理器

实现自定义异常页面的功能。支持通过配置文件配置异常及返回的页面,可设置不支持的异常;

public class SimpleMappingExceptionResolver extends AbstractHandlerExceptionResolver {
    //**配置的异常页面
	private Properties exceptionMappings;
    //**不支持的异常
	private Class<?>[] excludedExceptions;

	protected ModelAndView doResolveException(
			HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) {
		//**获取当前异常的返回页面
		String viewName = determineViewName(ex, request);
		if (viewName != null) {
			...
		} else {
			return null;
		}
	}

    //**获取当前异常的页面,如果是不支持的异常,则直接返回null(处理失败)
	protected String determineViewName(Exception ex, HttpServletRequest request) {
		String viewName = null;
		if (this.excludedExceptions != null) {
			for (Class<?> excludedEx : this.excludedExceptions) {
				if (excludedEx.equals(ex.getClass())) {
					return null;
				}
			}
		}
		//**如果配置了异常页面,则查找当前异常的返回页面
		if (this.exceptionMappings != null) {
			viewName = findMatchingViewName(this.exceptionMappings, ex);
		}
		....
		return viewName;
	}
}

4.6.ResponseStatusExceptionResolver异常处理器

处理ResponseStatusException和@ResponseStatus标注的自定义异常,并且会递归查找上级异常;

public class ResponseStatusExceptionResolver extends AbstractHandlerExceptionResolver implements MessageSourceAware {
	//**国际化
	private MessageSource messageSource;

    //**处理ResponseStatusException和@ResponseStatus标注的自定义异常
	protected ModelAndView doResolveException(
			HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) {
		try {
			if (ex instanceof ResponseStatusException) { //**处理ResponseStatusException
				return resolveResponseStatusException((ResponseStatusException) ex, request, response, handler);
			}
            
            //**处理@ResponseStatus标注的自定义异常
			ResponseStatus status = AnnotatedElementUtils.findMergedAnnotation(ex.getClass(), ResponseStatus.class);
			if (status != null) {
				return resolveResponseStatus(status, request, response, handler, ex);
			}
            
            //**如果都不是则递归查找上级异常是否是ResponseStatusException和@ResponseStatus标注的自定义异常
			if (ex.getCause() instanceof Exception) {
				return doResolveException(request, response, handler, (Exception) ex.getCause());
			}
		}
		...
		return null;
	}
}

4.7.DefaultHandlerExceptionResolver异常处理器

支持常见的异常处理;

public class DefaultHandlerExceptionResolver extends AbstractHandlerExceptionResolver {
	//**支持常见的异常
	protected ModelAndView doResolveException(
			HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) {

		try {
			if (ex instanceof HttpRequestMethodNotSupportedException) {
				return handleHttpRequestMethodNotSupported(
						(HttpRequestMethodNotSupportedException) ex, request, response, handler);
			}
			else if (ex instanceof HttpMediaTypeNotSupportedException) {
				return handleHttpMediaTypeNotSupported(
						(HttpMediaTypeNotSupportedException) ex, request, response, handler);
			}
			else if (ex instanceof HttpMediaTypeNotAcceptableException) {
				return handleHttpMediaTypeNotAcceptable(
						(HttpMediaTypeNotAcceptableException) ex, request, response, handler);
			}
			else if (ex instanceof MissingPathVariableException) {
				return handleMissingPathVariable(
						(MissingPathVariableException) ex, request, response, handler);
			}
			else if (ex instanceof MissingServletRequestParameterException) {
				return handleMissingServletRequestParameter(
						(MissingServletRequestParameterException) ex, request, response, handler);
			}
			else if (ex instanceof ServletRequestBindingException) {
				return handleServletRequestBindingException(
						(ServletRequestBindingException) ex, request, response, handler);
			}
			else if (ex instanceof ConversionNotSupportedException) {
				return handleConversionNotSupported(
						(ConversionNotSupportedException) ex, request, response, handler);
			}
			else if (ex instanceof TypeMismatchException) {
				return handleTypeMismatch(
						(TypeMismatchException) ex, request, response, handler);
			}
			else if (ex instanceof HttpMessageNotReadableException) {
				return handleHttpMessageNotReadable(
						(HttpMessageNotReadableException) ex, request, response, handler);
			}
			else if (ex instanceof HttpMessageNotWritableException) {
				return handleHttpMessageNotWritable(
						(HttpMessageNotWritableException) ex, request, response, handler);
			}
			else if (ex instanceof MethodArgumentNotValidException) {
				return handleMethodArgumentNotValidException(
						(MethodArgumentNotValidException) ex, request, response, handler);
			}
			else if (ex instanceof MissingServletRequestPartException) {
				return handleMissingServletRequestPartException(
						(MissingServletRequestPartException) ex, request, response, handler);
			}
			else if (ex instanceof BindException) {
				return handleBindException((BindException) ex, request, response, handler);
			}
			else if (ex instanceof NoHandlerFoundException) {
				return handleNoHandlerFoundException(
						(NoHandlerFoundException) ex, request, response, handler);
			}
			else if (ex instanceof AsyncRequestTimeoutException) {
				return handleAsyncRequestTimeoutException(
						(AsyncRequestTimeoutException) ex, request, response, handler);
			}
		}
		..
		return null;
	}
}

4.8.AbstractHandlerMethodExceptionResolver异常处理器

处理HandlerMethod产生的异常,HandlerMethod是spring对bean中的方法的封装;

public abstract class AbstractHandlerMethodExceptionResolver extends AbstractHandlerExceptionResolver {
    //**判断是否支持当前的handler,只支持HandlerMethod产生的异常
	protected boolean shouldApplyTo(HttpServletRequest request, @Nullable Object handler) {
		if (handler == null) {
			return super.shouldApplyTo(request, null);
		}
		else if (handler instanceof HandlerMethod) {
			HandlerMethod handlerMethod = (HandlerMethod) handler;
			//**判断是否支持当前的handler所属的类
			handler = handlerMethod.getBean();
			return super.shouldApplyTo(request, handler);
		}
		else {
			return false;
		}
	}

    //**把父类的handler(Object)转换为handler(HandlerMethod)
	protected final ModelAndView doResolveException(
			HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) {

		return doResolveHandlerMethodException(request, response, (HandlerMethod) handler, ex);
	}
	
	//**转换后的异常处理方法
	protected abstract ModelAndView doResolveHandlerMethodException(
			HttpServletRequest request, HttpServletResponse response, @Nullable HandlerMethod handlerMethod, Exception ex);

}

4.9.ExceptionHandlerExceptionResolver异常处理器

  • 调用配置的异常处理方法处理异常,在异常处理方法可设置@RequestAttribute等参数(像Controller一样);
  • 优先从handler当前类中查找异常处理方法。如果不存在,则从全局的ControllerAdvice类中查找异常处理方法;
public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExceptionResolver
		implements ApplicationContextAware, InitializingBean {
    //**参数处理器,处理配置的全局异常处理器中的参数(如@RequestAttribute标注的参数)
	private List<HandlerMethodArgumentResolver> customArgumentResolvers;
	//**组合的参数处理器
	private HandlerMethodArgumentResolverComposite argumentResolvers;

    //**返回值处理器,处理配置的全局异常处理器中的返回值
	private List<HandlerMethodReturnValueHandler> customReturnValueHandlers;
    //**组合的返回值处理器
	private HandlerMethodReturnValueHandlerComposite returnValueHandlers;
	
    //**存放类和它使用过的方法异常处理器
	private final Map<Class<?>, ExceptionHandlerMethodResolver> exceptionHandlerCache = new ConcurrentHashMap<>(64);

    //**存放配置的ControllerAdvice类和它支持方法异常处理器 
	private final Map<ControllerAdviceBean, ExceptionHandlerMethodResolver>exceptionHandlerAdviceCache = new LinkedHashMap<>();

	@Override
	public void afterPropertiesSet() {
		//**初始化ControllerAdvice类
		initExceptionHandlerAdviceCache();
        
        //**获取参数处理器并组装为HandlerMethodArgumentResolverComposite
		if (this.argumentResolvers == null) {
			List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();
			this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
		}
		
		//**获取返回值处理器并组装为HandlerMethodReturnValueHandlerComposite
		if (this.returnValueHandlers == null) {
			List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers();
			this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
		}
	}

    //**获取ControllerAdvice类,并创建对应的ExceptionHandlerMethodResolver
	private void initExceptionHandlerAdviceCache() {
        ...
        //**获取所有的ControllerAdvice类
		List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
		//**排序
		AnnotationAwareOrderComparator.sort(adviceBeans);

		for (ControllerAdviceBean adviceBean : adviceBeans) {
			...
			//**创建ExceptionHandlerMethodResolver并存放到exceptionHandlerAdviceCache中
			ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(beanType);
			if (resolver.hasExceptionMappings()) {
				this.exceptionHandlerAdviceCache.put(adviceBean, resolver);
			}
		}
        ...
	}

	//**获取参数处理器(默认的参数处理器+配置的参数处理器)
	protected List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {
		List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();

		// Annotation-based argument resolution
		resolvers.add(new SessionAttributeMethodArgumentResolver());
		resolvers.add(new RequestAttributeMethodArgumentResolver());

		// Type-based argument resolution
		resolvers.add(new ServletRequestMethodArgumentResolver());
		resolvers.add(new ServletResponseMethodArgumentResolver());
		resolvers.add(new RedirectAttributesMethodArgumentResolver());
		resolvers.add(new ModelMethodProcessor());

		// Custom arguments
		if (getCustomArgumentResolvers() != null) {
			resolvers.addAll(getCustomArgumentResolvers());
		}

		return resolvers;
	}

	//**获取返回值处理器(默认的返回值处理器+配置的返回值处理器)
	protected List<HandlerMethodReturnValueHandler> getDefaultReturnValueHandlers() {
		List<HandlerMethodReturnValueHandler> handlers = new ArrayList<>();

		// Single-purpose return value types
		handlers.add(new ModelAndViewMethodReturnValueHandler());
		handlers.add(new ModelMethodProcessor());
		handlers.add(new ViewMethodReturnValueHandler());
		handlers.add(new HttpEntityMethodProcessor(
				getMessageConverters(), this.contentNegotiationManager, this.responseBodyAdvice));

		// Annotation-based return value types
		handlers.add(new ModelAttributeMethodProcessor(false));
		handlers.add(new RequestResponseBodyMethodProcessor(
				getMessageConverters(), this.contentNegotiationManager, this.responseBodyAdvice));

		// Multi-purpose return value types
		handlers.add(new ViewNameMethodReturnValueHandler());
		handlers.add(new MapMethodProcessor());

		// Custom return value types
		if (getCustomReturnValueHandlers() != null) {
			handlers.addAll(getCustomReturnValueHandlers());
		}

		// Catch-all
		handlers.add(new ModelAttributeMethodProcessor(true));

		return handlers;
	}
    
    //**处理异常
	protected ModelAndView doResolveHandlerMethodException(HttpServletRequest request,
			HttpServletResponse response, @Nullable HandlerMethod handlerMethod, Exception exception) {
        //**获取方法调用处理器
		ServletInvocableHandlerMethod exceptionHandlerMethod = getExceptionHandlerMethod(handlerMethod, exception);
		if (exceptionHandlerMethod == null) {
			return null;
		}
        //**给方法调用处理器设置参数处理器
		if (this.argumentResolvers != null) {
			exceptionHandlerMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
		}
		//**给方法调用处理器设置返回值处理器
		if (this.returnValueHandlers != null) {
			exceptionHandlerMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
		}

		ServletWebRequest webRequest = new ServletWebRequest(request, response);
        ...
		try {
			Throwable cause = exception.getCause();
			//**如果存在上级异常,则调用异常处理方法处理上级异常
			if (cause != null) {
				exceptionHandlerMethod.invokeAndHandle(webRequest, mavContainer, exception, cause, handlerMethod);
			}
			else { //**调用异常处理方法处理当前异常
				exceptionHandlerMethod.invokeAndHandle(webRequest, mavContainer, exception, handlerMethod);
			}
		}
		...
	}
    
    //**根据handler和异常获取方法调用处理器。先从handler的类中查找,在去ControllerAdvice类中查找
    //**方法调用处理器负责调用配置的异常处理方法,包括解析@RequestAttribute等参数,处理返回结果
	protected ServletInvocableHandlerMethod getExceptionHandlerMethod(
			@Nullable HandlerMethod handlerMethod, Exception exception) {

		Class<?> handlerType = null;

		if (handlerMethod != null) {
			//**从exceptionHandlerCache获取当前类使用过的处理器,如果没有则创建一个,并存放到exceptionHandlerCache中
			handlerType = handlerMethod.getBeanType();
			ExceptionHandlerMethodResolver resolver = this.exceptionHandlerCache.get(handlerType);
			if (resolver == null) {
				resolver = new ExceptionHandlerMethodResolver(handlerType);
				this.exceptionHandlerCache.put(handlerType, resolver);
			}
			//**从当前handler中查找配置的异常处理方法
			Method method = resolver.resolveMethod(exception);
			if (method != null) {
				return new ServletInvocableHandlerMethod(handlerMethod.getBean(), method);
			}

			if (Proxy.isProxyClass(handlerType)) {
				handlerType = AopUtils.getTargetClass(handlerMethod.getBean());
			}
		}
        
        //**从ControllerAdvice类中查找异常处理方法
		for (Map.Entry<ControllerAdviceBean, ExceptionHandlerMethodResolver> entry : this.exceptionHandlerAdviceCache.entrySet()) {
			ControllerAdviceBean advice = entry.getKey();
			if (advice.isApplicableToBeanType(handlerType)) {
				ExceptionHandlerMethodResolver resolver = entry.getValue();
				Method method = resolver.resolveMethod(exception);
				if (method != null) {
					return new ServletInvocableHandlerMethod(advice.resolveBean(), method);
				}
			}
		}

		return null;
	}
}

4.10.ExceptionHandlerMethodResolver异常处理器

public class ExceptionHandlerMethodResolver {
    //**过滤异常处理方法
	public static final MethodFilter EXCEPTION_HANDLER_METHODS = method ->
			AnnotatedElementUtils.hasAnnotation(method, ExceptionHandler.class);
    //**存放类中所有的异常和处理方法
	private final Map<Class<? extends Throwable>, Method> mappedMethods = new HashMap<>(16);
    //**存放当前异常和异常处理方法
	private final Map<Class<? extends Throwable>, Method> exceptionLookupCache = new ConcurrentReferenceHashMap<>(16);
    
    //**查找类中的所有异常处理方法,并存放到mappedMethods中
	public ExceptionHandlerMethodResolver(Class<?> handlerType) {
		for (Method method : MethodIntrospector.selectMethods(handlerType, EXCEPTION_HANDLER_METHODS)) {
			for (Class<? extends Throwable> exceptionType : detectExceptionMappings(method)) {
				addExceptionMapping(exceptionType, method);
			}
		}
	}

	//**根据异常获取异常处理方法
	public Method resolveMethod(Exception exception) {
		return resolveMethodByThrowable(exception);
	}

	//**根据异常获取异常处理方法(会递归查找上级异常)
	public Method resolveMethodByThrowable(Throwable exception) {
		Method method = resolveMethodByExceptionType(exception.getClass());
		if (method == null) {
			Throwable cause = exception.getCause();
			if (cause != null) {
				method = resolveMethodByExceptionType(cause.getClass());
			}
		}
		return method;
	}

    //**根据异常的class对象获取异常处理方法(先从exceptionLookupCache中查找,如果不存在则计算,然后保存在exceptionLookupCache中)
	public Method resolveMethodByExceptionType(Class<? extends Throwable> exceptionType) {
		Method method = this.exceptionLookupCache.get(exceptionType);
		if (method == null) {
			method = getMappedMethod(exceptionType);
			this.exceptionLookupCache.put(exceptionType, method);
		}
		return method;
	}
    
    //**从mappedException中查找异常处理方法,并获取优先度最高的一个
	private Method getMappedMethod(Class<? extends Throwable> exceptionType) {
		List<Class<? extends Throwable>> matches = new ArrayList<>();
		for (Class<? extends Throwable> mappedException : this.mappedMethods.keySet()) {
			if (mappedException.isAssignableFrom(exceptionType)) {
				matches.add(mappedException);
			}
		}
		if (!matches.isEmpty()) {
			matches.sort(new ExceptionDepthComparator(exceptionType));
			return this.mappedMethods.get(matches.get(0));
		}
		else {
			return null;
		}
	}
}
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐