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()方法。