spring request的处理过程
2018-03-05 22:21
211 查看
在spring项目中,一个request过来后,都经过了哪些步骤才到controller那里呢?
下面直接亮出结论,有兴趣的可以继续往下读(当然了,只是粗略的记录,要想深刻理解,还需要自己一步步跟进去看)。
1、经过servlet框架的filter
2、进入FrameworkServlet#processRequest(...)(spring的),经过若干层会进入到DispatcherServlet.doDispatch(),这个是重点
2.1 在这个dispatch里面,先从众多的HandlerMapping里获取第一个不为null的HandlerExecutionChain,每个HandlerMapping都实现接口HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
2.2 然后执行HandlerExecutionChain.applyPreHandle(),这个嘛就是interceptor。2.3 接着执行HandlerAdapter.handle(),这个嘛,进入HanderAdapter,Valid注解检查、aop都在这里,详细的可看下文。
2.4 如果没异常抛出来的话(被aop吃掉的异常不算)最后执行HandlerExecutionChain.applyPostHandle(),这个也是interceptor。
3、然后基本就没了
。
先贴上几个图,辅助理解
下面直接亮出结论,有兴趣的可以继续往下读(当然了,只是粗略的记录,要想深刻理解,还需要自己一步步跟进去看)。
1、经过servlet框架的filter
2、进入FrameworkServlet#processRequest(...)(spring的),经过若干层会进入到DispatcherServlet.doDispatch(),这个是重点
2.1 在这个dispatch里面,先从众多的HandlerMapping里获取第一个不为null的HandlerExecutionChain,每个HandlerMapping都实现接口HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
2.2 然后执行HandlerExecutionChain.applyPreHandle(),这个嘛就是interceptor。2.3 接着执行HandlerAdapter.handle(),这个嘛,进入HanderAdapter,Valid注解检查、aop都在这里,详细的可看下文。
2.4 如果没异常抛出来的话(被aop吃掉的异常不算)最后执行HandlerExecutionChain.applyPostHandle(),这个也是interceptor。
3、然后基本就没了
。
先贴上几个图,辅助理解
一、HandlerMapping——是接口
HandlerMapping是个接口,代表着具有如下功能的类:即从给定的HttpServletRequest,找到合适Handler。其作用就是返回一个HandlerExecutionChain。常见的有RequestMappingHandlerMapping、SimpleUrlHandlerMapping。第一个就是通过扫描spring的@RequestMapping注解来得到映射关系。一个HandlerMapping通过HandlerExecutionChain的形式返回当前request的HandlerAdapter(及其对应的HandlerInterceptor,HandlerInterceptor的preHandle和postHandle分别在在HandlerAdapter的之前和之后执行(都是按定义顺序挨个执行))。二、HandlerExecutionChain——是个类
在beanFactory里没有这样类型的bean,用到的时候就new一个。包含一个HandlerAdapter和多个HandlerInterceptor,每个请求都会对应到一个具体的方法,HandlerAdapter则包装了那个方法,而HandlerInterceptor就是在执行HandlerAdapter之前需要执行的一些interceptor。(aop还在HandlerAdapter里面)。三、RequestMappingHandlerAdapter——是个类
在beanFactory里有一个这个类型的bean。内部成员有HttpMessageConverter、HandlerMethodArgumentResolver和HandlerMethodReturnValueHandler,分别用于处理被调方法的入参和返回值,HttpMessageConverter是代表具体的转换动作的类。RequestResponseBodyMethodProcessor同时实现了HandlerMethodArgumentResolver和HandlerMethodReturnValueHandler。RequestMappingHandlerAdapter有个afterPropertiesSet(),里面有个getDefaultArgumentResolvers,代码里写死了只添加默认的HandlerMethodArgumentResolver。加上只查找第一个support的HandlerMethodArgumentResolver。所以要想包装RequestResponseBodyMethodProcessor的行为,只能自定义一个注解,并且自定义一个HandlerAdapter,也就是要自定义一个HandlerMapping。四、HandlerMethodArgumentResolver
HandlerAdapter.handle(),这个方法里是按如下的层级结构执行的。HandlerAdapter#handle(HttpServletRequest request, HttpServletResponse response, Object handler) AbstractHandlerMethodAdapter.handler(HttpServletRequest request, HttpServletResponse response, Object handler) RequestMappingHandlerAdapter.handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) RequestMappingHandlerAdapter.invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) ServletInvocableHandlerMethod.invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer, Object... providedArgs) InvocableHandlerMethod.invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer, Object... providedArgs) InvocableHandlerMethod.getMethodArgumentValues(NativeWebRequest request, ModelAndViewContainer mavContainer, Object... providedArgs) // HandlerMethodArgumentResolverComposite代理了多个HandlerMethodArgumentResolver,每次选出一个何时的出来进行解析。RequestResponseBodyMethodProcessor就是其中之一 HandlerMethodArgumentResolverComposite.resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) // 下面这个在RequestResponseBodyMethodProcessor#resolveArgument(…)里;在调用下面这个之前,先调用HttpMessageConverter得到参数值,然后准备校验。 AbstractMessageConverterMethodArgumentResolver.validateIfApplicable(WebDataBinder binder, MethodParameter methodParam) … 进入SpringValidatorAdapter.validate(Object target, Errors errors, Object... validationHints) // org.hibernate.validator.internal.engine ValidatorImpl.validate(T object, Class<?>... groups) 这里面有个临时变量ValueContext.currentValidatable,这个属性的值是BeanMetaDataManager.getBeanMetaData( object.getClass() ) 这个里面取的是编译时的类型,这个object就是某个参数,而非运行时。 ValidatorImpl.validateCascadedConstraints(ValidationContext<?> validationContext, ValueContext<?, Object> valueContext) 里面拿到一个属性的value后,应该通过value.getClass()来重新计算设定类类型,这样可以支持泛型。而非直接调用Cascadable(PropertyMetaData).getTypeArgumentsConstraints()
五、RequestResponseBodyMethodProcessor
在beanFactory里没有这个类型的bean,用到的时候就new一个。这个类同时实现HandlerMethodReturnValueHandler、HandlerMethodArgumentResolver。内部成员有HttpMessageConverter,这个是从beanFactory里取的。使用HttpMessageConverter处理加了@RequestBody和@ResponseBody注解的那些方法入参和返回值。如果入参还加了@Valid注解,那么还会执行相应的校验,如果校验失败,会抛出异常MethodArgumentNotValidException,该异常不会被aop捕获(因为还未进入aop呢)且HTTP RESPONSE的状态是400。若要修改,则包装RequestResponseBodyMethodProcessor.resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory);即可。相关文章推荐
- SpringMVC @RequestBody接收Json对象字符串 @ResponseBody处理json数据类型
- spring事务处理:调用一个方法前的事务处理过程
- spring mvc DispatcherServlet详解之三---request通过ModelAndView中获取View实例的过程
- Spring aop事务代理对象通过TransactionInterceptor处理目标方法事务过程,cglib方式
- Tomcat源码分析(四)------ Request和Response处理的全过程
- Spring Boot :Request请求处理流程
- Spring3.2 Http 请求处理过程笔记
- Spring Web MVC 处理Http请求的大致过程
- aiohttp 源码解析之 request 的处理过程
- Tomcat源码分析(四)------ Request和Response处理的全过程
- spring RequestMappingHandlerAdapter解析参数绑定到pojo过程
- Tomcat源码分析(四)------ Request和Response处理的全过程
- Spring3.2 Http 请求处理过程笔记
- (十一)Spring事务处理 - 事务处理的过程
- Tomcat源码分析之四_Request和Response处理的全过程
- spring源码学习之五 </context:component-scan>元素处理过程
- spring源码分析,view的处理过程
- 请求与响应原理图及Tomcat对request的处理过程
- Spring createBean过程中BeanPostProcessor的处理机会
- Spring Web MVC 处理Http请求的过程(SpringMVC 原理)