@RestControllerAdvice与@ExceptionHandler注解源码详解

一、处理流程

@RestControllerAdvice与@ExceptionHandler注解是sprngmvc中与异常捕获与处理相关的注解,它的入口也是DispatcherServlet中的doDispatcher()方法中,如下:
this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
后面会进入HandlerExceptionResolverComposite的resolveException方法,这个ExceptionHandlerResolverComposite包含三个ExcpetionHandlerResolver,是在springmvc中生成的,在springboot中其生成代码如下:
	@Bean
	public HandlerExceptionResolver handlerExceptionResolver() {
		List exceptionResolvers = new ArrayList<>();
		configureHandlerExceptionResolvers(exceptionResolvers);
		if (exceptionResolvers.isEmpty()) {
			addDefaultHandlerExceptionResolvers(exceptionResolvers);
		}
		extendHandlerExceptionResolvers(exceptionResolvers);
		HandlerExceptionResolverComposite composite = new HandlerExceptionResolverComposite();
		composite.setOrder(0);
		composite.setExceptionResolvers(exceptionResolvers);
		return composite;
	}
后面他会进入ExceptionHandlerExceptionResolver类的方法:

	protected ModelAndView doResolveHandlerMethodException(HttpServletRequest request,
			HttpServletResponse response, @Nullable HandlerMethod handlerMethod, Exception exception) {

		ServletInvocableHandlerMethod exceptionHandlerMethod = getExceptionHandlerMethod(handlerMethod, exception);
在这个方法中的第一行, getExceptionHandlerMethod方法,其进行了查找对应的带有@ControllerAdvice注解的类型和对应匹配的方法,然后在doResolverHandlerMethod方法中进行了处理,这就是整个流程,那么我们现在流程分析完了,后面就是查看@ControllerAdvice这个bean是在什么时候什么地方加入到spring中的了,后面进行第二步分析:

二、bean载入分析

首先在springboot扫描的时候,会把@ControllerAdvice的bean放入到beanFactory里面去,此时只要从beanFactory中获取到需要的bean即可,处理方式在ExceptionHandlerExceptionResolver类中:

	@Override
	public void afterPropertiesSet() {
		// Do this first, it may add ResponseBodyAdvice beans
		initExceptionHandlerAdviceCache();
	private void initExceptionHandlerAdviceCache() {
		if (getApplicationContext() == null) {
			return;
		}
		if (logger.isDebugEnabled()) {
			logger.debug("Looking for exception mappings: " + getApplicationContext());
		}

		List adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
封装好后,获取带有@Exceptionhandler的注解方法,即根据异常类型进行调用了。



你可能感兴趣的:(spring源码)