@ControllerAdvice源码解析

在bean 初始化后

RequestMappingHandlerAdapter

public void afterPropertiesSet() {
   // 初始化controllerAdvice
    this.initControllerAdviceCache();
    List handlers;
    if (this.argumentResolvers == null) {
        handlers = this.getDefaultArgumentResolvers();
        this.argumentResolvers = (new HandlerMethodArgumentResolverComposite()).addResolvers(handlers);
    }

    if (this.initBinderArgumentResolvers == null) {
        handlers = this.getDefaultInitBinderArgumentResolvers();
        this.initBinderArgumentResolvers = (new HandlerMethodArgumentResolverComposite()).addResolvers(handlers);
    }

    if (this.returnValueHandlers == null) {
        handlers = this.getDefaultReturnValueHandlers();
        this.returnValueHandlers = (new HandlerMethodReturnValueHandlerComposite()).addHandlers(handlers);
    }

}


private void initControllerAdviceCache() {
    if (this.getApplicationContext() != null) {
        //获得有注解@ControllerAdvice的bean
        List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(this.getApplicationContext());
        List<Object> requestResponseBodyAdviceBeans = new ArrayList();
        Iterator var3 = adviceBeans.iterator();

        while(var3.hasNext()) {
            ControllerAdviceBean adviceBean = (ControllerAdviceBean)var3.next();
            Class<?> beanType = adviceBean.getBeanType();
            if (beanType == null) {
                throw new IllegalStateException("Unresolvable type for ControllerAdviceBean: " + adviceBean);
            }
           //获取@ControllerAdvice的bean 中的 @ModelAttribute注解的方法集合,放入map集合中modelAttributeAdviceCache

            Set<Method> attrMethods = MethodIntrospector.selectMethods(beanType, MODEL_ATTRIBUTE_METHODS);
            if (!attrMethods.isEmpty()) {
                this.modelAttributeAdviceCache.put(adviceBean, attrMethods);
            }

             //获取@ControllerAdvice的bean 中的 @InitBinder注解的方法集合,放入map集合中initBinderAdviceCache
          Set<Method> binderMethods = MethodIntrospector.selectMethods(beanType, INIT_BINDER_METHODS);
          if (!binderMethods.isEmpty()) {
           this.initBinderAdviceCache.put(adviceBean, binderMethods);
}






ExceptionHandlerExceptionResolver

而在ExceptionHandlerExceptionResolver 里面会将HanderException全部加入map缓存exceptionHandlerAdviceCache

private void initExceptionHandlerAdviceCache() {
    if (this.getApplicationContext() != null) {
        List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(this.getApplicationContext());
        Iterator var2 = adviceBeans.iterator();

        while(var2.hasNext()) {
            ControllerAdviceBean adviceBean = (ControllerAdviceBean)var2.next();
            Class<?> beanType = adviceBean.getBeanType();
            if (beanType == null) {
                throw new IllegalStateException("Unresolvable type for ControllerAdviceBean: " + adviceBean);
            }

            //这里 new ExceptionHandlerMethodResolver(beanType)会找到被@HanderException标注的注解
            ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(beanType);
            if (resolver.hasExceptionMappings()) {
                this.exceptionHandlerAdviceCache.put(adviceBean, resolver);
            }

            if (ResponseBodyAdvice.class.isAssignableFrom(beanType)) {
                this.responseBodyAdvice.add(adviceBean);
            }
        }

然后开发发送一个请求
http://localhost:9000/kangtest/putCachetest

首先是serlvet的void init(ServletConfig var1) throws ServletException;初始化方法, GenericServlet 实现了这个方法,

public void init(ServletConfig config) throws ServletException {
    this.config = config;
    this.init();
}

public void init() throws ServletException {
}

然后调用init()

HttpServletBean实现了init

public final void init() throws ServletException {
    PropertyValues pvs = new HttpServletBean.ServletConfigPropertyValues(this.getServletConfig(), this.requiredProperties);
    if (!pvs.isEmpty()) {
        try {
            BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
            ResourceLoader resourceLoader = new ServletContextResourceLoader(this.getServletContext());
            bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.getEnvironment()));
            this.initBeanWrapper(bw);
            bw.setPropertyValues(pvs, true);
        } catch (BeansException var4) {
            if (this.logger.isErrorEnabled()) {
                this.logger.error("Failed to set bean properties on servlet '" + this.getServletName() + "'", var4);
            }

            throw var4;
        }
    }

    this.initServletBean();
}


调用initServletBean	,FrameworkServlet重写initServletBean,调用initWebApplicationContext  初始化webmvc上下文,然后调用 this.onRefresh(wac);



protected final void initServletBean() throws ServletException {
    this.getServletContext().log("Initializing Spring " + this.getClass().getSimpleName() + " '" + this.getServletName() + "'");
    if (this.logger.isInfoEnabled()) {
        this.logger.info("Initializing Servlet '" + this.getServletName() + "'");
    }

    long startTime = System.currentTimeMillis();

    try {
        this.webApplicationContext = this.initWebApplicationContext();
        this.initFrameworkServlet();
    } catch (RuntimeException | ServletException var4) {
        this.logger.error("Context initialization failed", var4);
        throw var4;
    }

    if (this.logger.isDebugEnabled()) {
        String value = this.enableLoggingRequestDetails ? "shown which may lead to unsafe logging of potentially sensitive data" : "masked to prevent unsafe logging of potentially sensitive data";
        this.logger.debug("enableLoggingRequestDetails='" + this.enableLoggingRequestDetails + "': request parameters and headers will be " + value);
    }

    if (this.logger.isInfoEnabled()) {
        this.logger.info("Completed initialization in " + (System.currentTimeMillis() - startTime) + " ms");
    }

}


protected WebApplicationContext initWebApplicationContext() {
    WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
    WebApplicationContext wac = null;
    if (this.webApplicationContext != null) {
        wac = this.webApplicationContext;
        if (wac instanceof ConfigurableWebApplicationContext) {
            ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext)wac;
            if (!cwac.isActive()) {
                if (cwac.getParent() == null) {
                    cwac.setParent(rootContext);
                }

                this.configureAndRefreshWebApplicationContext(cwac);
            }
        }
    }

    if (wac == null) {
        wac = this.findWebApplicationContext();
    }

    if (wac == null) {
        wac = this.createWebApplicationContext(rootContext);
    }

    if (!this.refreshEventReceived) {
        synchronized(this.onRefreshMonitor) {
            this.onRefresh(wac);
        }
    }






DispatcherServlet 继承FrameworkServlet,重写onRefresh ,调用initStrategies 初始化

protected void onRefresh(ApplicationContext context) {
    this.initStrategies(context);
}

protected void initStrategies(ApplicationContext context) {
    this.initMultipartResolver(context);
    this.initLocaleResolver(context);
    this.initThemeResolver(context);
    //初始化HanderMapping
    this.initHandlerMappings(context);
 //初始化HanderAdapters
    this.initHandlerAdapters(context);
//初始化hander异常处理
    this.initHandlerExceptionResolvers(context);
    this.initRequestToViewNameTranslator(context);
    this.initViewResolvers(context);
    this.initFlashMapManager(context);
}



private void initHandlerMappings(ApplicationContext context) {
    this.handlerMappings = null;
    if (this.detectAllHandlerMappings) {
     //得到handlerMapping
        Map<String, HandlerMapping> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
        if (!matchingBeans.isEmpty()) {
            this.handlerMappings = new ArrayList(matchingBeans.values());
            AnnotationAwareOrderComparator.sort(this.handlerMappings);
        }
    } else {
        try {
            HandlerMapping hm = (HandlerMapping)context.getBean("handlerMapping", HandlerMapping.class);
            this.handlerMappings = Collections.singletonList(hm);
        } catch (NoSuchBeanDefinitionException var4) {
        }
    }

    if (this.handlerMappings == null) {
        this.handlerMappings = this.getDefaultStrategies(context, HandlerMapping.class);
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("No HandlerMappings declared for servlet '" + this.getServletName() + "': using default strategies from DispatcherServlet.properties");
        }
    }

    Iterator var6 = this.handlerMappings.iterator();

    while(var6.hasNext()) {
        HandlerMapping mapping = (HandlerMapping)var6.next();
        if (mapping.usesPathPatterns()) {
            this.parseRequestPath = true;
            break;
        }
    }

}

在这里插入图片描述

得到handerAdapter

private void initHandlerAdapters(ApplicationContext context) {
    this.handlerAdapters = null;
    if (this.detectAllHandlerAdapters) {
        Map<String, HandlerAdapter> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);
        if (!matchingBeans.isEmpty()) {
            this.handlerAdapters = new ArrayList(matchingBeans.values());
            AnnotationAwareOrderComparator.sort(this.handlerAdapters);
        }
    } else {
        try {
            HandlerAdapter ha = (HandlerAdapter)context.getBean("handlerAdapter", HandlerAdapter.class);
            this.handlerAdapters = Collections.singletonList(ha);
        } catch (NoSuchBeanDefinitionException var3) {
        }
    }

    if (this.handlerAdapters == null) {
        this.handlerAdapters = this.getDefaultStrategies(context, HandlerAdapter.class);
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("No HandlerAdapters declared for servlet '" + this.getServletName() + "': using default strategies from DispatcherServlet.properties");
        }
    }

}

在这里插入图片描述

初始化异常处理

private void initHandlerExceptionResolvers(ApplicationContext context) {
    this.handlerExceptionResolvers = null;
    if (this.detectAllHandlerExceptionResolvers) {
        Map<String, HandlerExceptionResolver> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerExceptionResolver.class, true, false);
        if (!matchingBeans.isEmpty()) {
            this.handlerExceptionResolvers = new ArrayList(matchingBeans.values());
            AnnotationAwareOrderComparator.sort(this.handlerExceptionResolvers);
        }
    } else {
        try {
            HandlerExceptionResolver her = (HandlerExceptionResolver)context.getBean("handlerExceptionResolver", HandlerExceptionResolver.class);
            this.handlerExceptionResolvers = Collections.singletonList(her);
        } catch (NoSuchBeanDefinitionException var3) {
        }
    }

    if (this.handlerExceptionResolvers == null) {
        this.handlerExceptionResolvers = this.getDefaultStrategies(context, HandlerExceptionResolver.class);
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("No HandlerExceptionResolvers declared in servlet '" + this.getServletName() + "': using default strategies from DispatcherServlet.properties");
        }
    }

}

在这里插入图片描述
出现异常是在dodispatcher中处理异常,处理完异常后走的后置处理器

this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值