ApplicationContext在Web容器中的启动
- 应用程序级别的上下文(根上下文):applicationContext.xml,一般加载非web的配置(Service、DataSource、DAO等)。
- web级别的上下文(子上下文):dispatcher-servlet.xml,专注于mvc的配置(Controller、HandlerMapping、HandlerAdapter、ViewResolver等)。
web容器启动时首先建立根上下文,由ContextLoaderListener
完成,子上下文是在DispatcherServlet
初始化时建立。
请求分发和处理
DispatcherServlet
是Spring MVC的核心组件,它负责接收HTTP请求并协调Spring MVC的各个组件完成请求处理的工作。
- 查找处理器,
DispatcherServlet
根据HanlderMapping
查找Handler
(xml配置、注解)进行查找。处理器映射器向前端控制器返回HandlerExecutionChain
,处理器执行链封装了具体的Handler
和拦截器链HandlerInterceptor
。 - 调用处理器适配器去执行
Handler
。 - 执行
Handler
并返回ModelAndView
。 - 前端控制器请求视图解析器去进行视图解析,根据逻辑视图名解析成真正的视图。
- 前端控制器进行视图渲染,将模型数据填充到Request。
HandlerMapping
HandlerMapping
在Spring启动时候就会注入到DispatcherServlet
中,它的初始化方式主要依赖于AbstractHandlerMethodMapping这个抽象类,利用initHandlerMethods(..)
方法获取所有Spring容器托管的bean,然后调用isHandler(..)
看是否是@Controller
注解修饰的bean,之后调用detectHandlerMethods(..)
尝试去解析bean中的方法,也就是去搜索@RequestMapping
注解修饰的方法,将前端请求的url path 和具体的 Method 来做关联映射。
完成所有的搜索bean搜索后,调用registerHandlerMethod(..)
将 Method 构造为HandlerMethod
,添加到HandlerMapping内含的属性列表中。private final Map<T, HandlerMethod> handlerMethods = new LinkedHashMap<T, HandlerMethod>();
(T是泛型的,具体存放的最简单就是url path信息)。
HandlerAdapter
调用HandlerAdpter
时会遍历所有配置在Spring容器已经配好的 handlerAdapters,调用supports(..)
方法,得到第一个返回为true的HandlerAdapter
,传入参数实际上就是上面提到的就是HandlerMethod
。 supports 主要就是验证某个HandlerMethod
上定义的参数、返回值解析,是否能由该handlerAdapter处理。
HandlerInterceptor
前端处理器在获取了HandlerAdapter
后,就开始执行拦截器链,遍历依次调用HandlerExecutionChain
的applyPreHandle(HttpServletRequest request, HttpServletResponse response)
开始应用拦截器,一个一个调用其preHandle()
方法;以及之后调用applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv)
并执行postHandle()
方法。