spring mvc 原理

匿名 (未验证) 提交于 2019-12-03 00:09:02

1.RequestMappingHandlerMapping

 

 1.继承了InitializingBean 加载所有的 Controller.class 和  RequestMapping.class

2. WebMvcAutoConfiguration   初始化时加载interception

 

 3.根据url 获取在RequestMappingHandlerMapping获取handlerMethod,并包装成HandlerExecutionChain,并将RequestMappingHandlerMapping中的intercepters加入到 HandlerExecutionChain

加入规则如下

protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {         HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?                 (HandlerExecutionChain) handler : new HandlerExecutionChain(handler));          String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);         for (HandlerInterceptor interceptor : this.adaptedInterceptors) {             if (interceptor instanceof MappedInterceptor) {                 MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;                 if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {                     chain.addInterceptor(mappedInterceptor.getInterceptor());                 }             }             else {                 chain.addInterceptor(interceptor);             }         }         return chain;     }

4.使用 handlerMethod 获取handlerAdapter 

4.1  RequestMappingHandlerAdapter (初始化时,初始化adviceCache,和参数解析器)

@Override     public void afterPropertiesSet() {         // Do this first, it may add ResponseBody advice beans         initControllerAdviceCache();          if (this.argumentResolvers == null) {             List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();             this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);         }         if (this.initBinderArgumentResolvers == null) {             List<HandlerMethodArgumentResolver> resolvers = getDefaultInitBinderArgumentResolvers();             this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);         }         if (this.returnValueHandlers == null) {             List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers();             this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);         }     }      private void initControllerAdviceCache() {         if (getApplicationContext() == null) {             return;         }          List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());         AnnotationAwareOrderComparator.sort(adviceBeans);          List<Object> requestResponseBodyAdviceBeans = new ArrayList<>();          for (ControllerAdviceBean adviceBean : adviceBeans) {             Class<?> beanType = adviceBean.getBeanType();             if (beanType == null) {                 throw new IllegalStateException("Unresolvable type for ControllerAdviceBean: " + adviceBean);             }             Set<Method> attrMethods = MethodIntrospector.selectMethods(beanType, MODEL_ATTRIBUTE_METHODS);             if (!attrMethods.isEmpty()) {                 this.modelAttributeAdviceCache.put(adviceBean, attrMethods);             }             Set<Method> binderMethods = MethodIntrospector.selectMethods(beanType, INIT_BINDER_METHODS);             if (!binderMethods.isEmpty()) {                 this.initBinderAdviceCache.put(adviceBean, binderMethods);             }             if (RequestBodyAdvice.class.isAssignableFrom(beanType) || ResponseBodyAdvice.class.isAssignableFrom(beanType)) {                 requestResponseBodyAdviceBeans.add(adviceBean);             }         }          if (!requestResponseBodyAdviceBeans.isEmpty()) {             this.requestResponseBodyAdvice.addAll(0, requestResponseBodyAdviceBeans);         }          if (logger.isDebugEnabled()) {             int modelSize = this.modelAttributeAdviceCache.size();             int binderSize = this.initBinderAdviceCache.size();             int reqCount = getBodyAdviceCount(RequestBodyAdvice.class);             int resCount = getBodyAdviceCount(ResponseBodyAdvice.class);             if (modelSize == 0 && binderSize == 0 && reqCount == 0 && resCount == 0) {                 logger.debug("ControllerAdvice beans: none");             }             else {                 logger.debug("ControllerAdvice beans: " + modelSize + " @ModelAttribute, " + binderSize +                         " @InitBinder, " + reqCount + " RequestBodyAdvice, " + resCount + " ResponseBodyAdvice");             }         }     }

5.使用handlerAdapter handler方法获取ModerAndView

mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

6.

在当前类和ControllerAdvice 中  获取 有InitBinder.class注解的方法全部封装在一起。(InitBinder用法https://blog.csdn.net/qq_38016931/article/details/82080940

在当前类和ControllerAdvice 中  获取 有ModelAttribute且没有RequestMapping 的注解的方法,全部封装在一起。(ModelAttribute用法https://blog.csdn.net/abc997995674/article/details/80464023

 7.将注解有ModelAttribute的方法,初始化后绑定到sessionAttributes;

8. resolvers解析参数  

例:RequestResponseBodyMethodProcessor 

8.1 1.使用 binder和 messageConverters 转化 json或xml,或其他的为对象。

8.2 valid 校验参数

9.参数解析正常 则调用代理对象

9.1使用代理对象的拦截器拦截方法,或初始化一些对象

9.2具体的方法调用

10.参数解析异常抛出异常

10.1

0 = {DefaultErrorAttributes@15395}
1 = {HandlerExceptionResolverComposite@12775}

10.2  HandlerExceptionResolverComposite里又含有三个异常

0 = {ExceptionHandlerExceptionResolver@15442}  --使用 @ExceptionHandler 解决异常   有些这里抛出的异常会导致 发起/error

1 = {ResponseStatusExceptionResolver@15443}  --解决@ResponseStatus或instanceof ResponseStatusException

2 = {DefaultHandlerExceptionResolver@12774} 针对于一些异常,重新发起(/error)请求

@Override     @Nullable     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);             }         }         catch (Exception handlerEx) {             if (logger.isWarnEnabled()) {                 logger.warn("Failure while trying to resolve exception [" + ex.getClass().getName() + "]", handlerEx);             }         }         return null;     }

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!