spring源码分析-web容器初始化过程解析1
2016-08-10 09:37
971 查看
在之前的“Spring MVC实现分析——初始化”中分析了spring mvc的初始化过程,接下来将分析其请求处理过程。
在找请求处理的入口时,我们需要先知道Servlet的编程规范,对应不同的请求(如POST、GET等)的实现方法在FrameworkServlet中,分别是doPost、doGet等,看这一系列方法的具体实现可以知道,请求的处理跳转到了processRequest函数中,最终进入DispatcherServlet的doService函数,详细的流程如:
上面的时序图展示了详细的请求处理流程,其中最重要的是doDispatch函数,其中包含了整个的处理逻辑,
[java] view
plain copy
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = AsyncWebUtils.getAsyncManager(request);
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
processedRequest = checkMultipart(request);
multipartRequestParsed = processedRequest != request;
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest, false);
if (mappedHandler == null || mappedHandler.getHandler() == null) {
noHandlerFound(processedRequest, response);
return;
}
// Determine handler adapter for the current request.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Process last-modified header, if supported by the handler.
……
try {
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
}
applyDefaultViewName(request, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
……
}
finally {
……
}
}
首先我们先看HandlerExecutionChain这个类中有些什么东西,
[java] view
plain copy
public class HandlerExecutionChain {
private final Object handler;
private HandlerInterceptor[] interceptors;
private List<HandlerInterceptor> interceptorList;
……
}
这里面有两个关键的东西handler与interceptors,也即处理器对象与拦截器链表,联系到我们实际的编程,handler有可能是两种东西:(1)controller类对象;(2)controller中的方法对象(用的术语可能不太准确……)。而interceptors也即我们定义拦截器对象列表,如果说想在请求被处理之前做点什么就会弄一个。明白了这一点,再来看看在doDispatch函数中如果获得HandlerExecutionChain对象mappedHandler。
可以看到其实现在getHandler方法中:
[java] view
plain copy
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
for (HandlerMapping hm : this.handlerMappings) {
……
HandlerExecutionChain handler = hm.getHandler(request);
if (handler != null) {
return handler;
}
}
return null;
}
函数的实现非常简单:遍历已注册的HandlerMapping列表,通过HandlerMapping对象的getHandler函数获取HandlerExecutionChain对象。至于HandlerMapping中的getHandler函数如何获取HandlerExecutionChain需要的处理器与拦截器,我只能说过程是繁琐的,原理是简单的,对于处理器对象(handler)根据不同的Mapping实现,其可以根据bean配置中的urlPath或者是方法的注解来寻找,这里不再细说。
顺着doDispatch函数的执行流程往下看,紧接着其通过getHandlerAdapter函数获得HandlerAdapter对象ha,然后就是又要重点照顾的一个调用:
[java] view
plain copy
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
随着调用HandlerAdapter的handle函数,Spring MVC便开始要真的“干实事”了,所谓的“干实事”也即开始调用执行我们编写的controller(控制逻辑)了。这里以两个HandlerAdapter的实现HttpRequestHandlerAdapter与AnnotationMethodHandlerAdapter来分析这个处理流程,在之前的一篇文章“Spring
MVC实现分析——初始化过程”中有提到我自己的一个Spring MVC程序配置,以此为准进行展开:
HttpRequestHandlerAdapter的实现是最容易理解的,因为其handle的实现就是调用了处理器(handler)对象的handleRequest函数,借助F4看看Controller的继承体系,再看看AbstractController中handleRequest函数的实现,结合自己菜鸟时期编写的Spring MVC “hello world程序”,你就会有恍然大悟的感觉⊙﹏⊙!
至于AnnotationMethodHandlerAdapter,其实现原理也是很容易理解的,我们已经知道其就是针对采用注解方式的方法映射的,实际应用中如:
[java] view
plain copy
@RequestMapping(method=RequestMethod.GET,value="/homeController.xhtml")
protected ModelAndView handleRequestInternal(HttpServletRequest arg0,
HttpServletResponse arg1) throws Exception {
……
}
所以其handle的实现就是通过java的反射机制找到注解对应的处理方法,并调用完成控制逻辑的执行。
此时,让我们再次回到doDispatch的处理流程上来,在经过handle的“干实事”后,我们得到了ModelAndView对象,也即视图对象,很自然接下来的就是视图的渲染与展示了,这也是我们最后要分析的一个点。其入口是doDispatch中的一个函数调用:
[java] view
plain copy
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
在找请求处理的入口时,我们需要先知道Servlet的编程规范,对应不同的请求(如POST、GET等)的实现方法在FrameworkServlet中,分别是doPost、doGet等,看这一系列方法的具体实现可以知道,请求的处理跳转到了processRequest函数中,最终进入DispatcherServlet的doService函数,详细的流程如:
上面的时序图展示了详细的请求处理流程,其中最重要的是doDispatch函数,其中包含了整个的处理逻辑,
[java] view
plain copy
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = AsyncWebUtils.getAsyncManager(request);
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
processedRequest = checkMultipart(request);
multipartRequestParsed = processedRequest != request;
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest, false);
if (mappedHandler == null || mappedHandler.getHandler() == null) {
noHandlerFound(processedRequest, response);
return;
}
// Determine handler adapter for the current request.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Process last-modified header, if supported by the handler.
……
try {
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
}
applyDefaultViewName(request, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
……
}
finally {
……
}
}
首先我们先看HandlerExecutionChain这个类中有些什么东西,
[java] view
plain copy
public class HandlerExecutionChain {
private final Object handler;
private HandlerInterceptor[] interceptors;
private List<HandlerInterceptor> interceptorList;
……
}
这里面有两个关键的东西handler与interceptors,也即处理器对象与拦截器链表,联系到我们实际的编程,handler有可能是两种东西:(1)controller类对象;(2)controller中的方法对象(用的术语可能不太准确……)。而interceptors也即我们定义拦截器对象列表,如果说想在请求被处理之前做点什么就会弄一个。明白了这一点,再来看看在doDispatch函数中如果获得HandlerExecutionChain对象mappedHandler。
可以看到其实现在getHandler方法中:
[java] view
plain copy
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
for (HandlerMapping hm : this.handlerMappings) {
……
HandlerExecutionChain handler = hm.getHandler(request);
if (handler != null) {
return handler;
}
}
return null;
}
函数的实现非常简单:遍历已注册的HandlerMapping列表,通过HandlerMapping对象的getHandler函数获取HandlerExecutionChain对象。至于HandlerMapping中的getHandler函数如何获取HandlerExecutionChain需要的处理器与拦截器,我只能说过程是繁琐的,原理是简单的,对于处理器对象(handler)根据不同的Mapping实现,其可以根据bean配置中的urlPath或者是方法的注解来寻找,这里不再细说。
顺着doDispatch函数的执行流程往下看,紧接着其通过getHandlerAdapter函数获得HandlerAdapter对象ha,然后就是又要重点照顾的一个调用:
[java] view
plain copy
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
随着调用HandlerAdapter的handle函数,Spring MVC便开始要真的“干实事”了,所谓的“干实事”也即开始调用执行我们编写的controller(控制逻辑)了。这里以两个HandlerAdapter的实现HttpRequestHandlerAdapter与AnnotationMethodHandlerAdapter来分析这个处理流程,在之前的一篇文章“Spring
MVC实现分析——初始化过程”中有提到我自己的一个Spring MVC程序配置,以此为准进行展开:
HttpRequestHandlerAdapter的实现是最容易理解的,因为其handle的实现就是调用了处理器(handler)对象的handleRequest函数,借助F4看看Controller的继承体系,再看看AbstractController中handleRequest函数的实现,结合自己菜鸟时期编写的Spring MVC “hello world程序”,你就会有恍然大悟的感觉⊙﹏⊙!
至于AnnotationMethodHandlerAdapter,其实现原理也是很容易理解的,我们已经知道其就是针对采用注解方式的方法映射的,实际应用中如:
[java] view
plain copy
@RequestMapping(method=RequestMethod.GET,value="/homeController.xhtml")
protected ModelAndView handleRequestInternal(HttpServletRequest arg0,
HttpServletResponse arg1) throws Exception {
……
}
所以其handle的实现就是通过java的反射机制找到注解对应的处理方法,并调用完成控制逻辑的执行。
此时,让我们再次回到doDispatch的处理流程上来,在经过handle的“干实事”后,我们得到了ModelAndView对象,也即视图对象,很自然接下来的就是视图的渲染与展示了,这也是我们最后要分析的一个点。其入口是doDispatch中的一个函数调用:
[java] view
plain copy
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
相关文章推荐
- Spring源码分析----IOC容器的实现(IoC容器的初始化过程(定位、载入解析、注册))
- spring源码研究之IoC容器在web容器中初始化过程
- spring源码学习之路---深度分析IOC容器初始化过程(四)
- spring源码研究之IoC容器在web容器中初始化过程
- spring容器初始化,bean加载生成过程,源码解析学习
- Spring源码解析之零 ------ 容器初始化过程(refresh()方法)概要
- spring源码学习之路---深度分析IOC容器初始化过程(四)
- spring源码学习之路---深度分析IOC容器初始化过程(三)
- Spring源码解析二:IOC容器初始化过程详解
- spring源码研究之IoC容器在web容器中初始化过程(转)
- spring源码学习之路---深度分析IOC容器初始化过程(四)
- 源码解读(一): spring在web容器中的初始化过程
- 转:Spring源码分析:IOC容器在web容器中的启动
- 从源码看spring applicationContext在web容器中加载过程
- Spring源码解读-Spring IoC容器初始化之资源解析
- Spring 初始化过程详细分析[源码](一)
- 深入理解 spring 容器,源码分析加载过程
- 小读spring ioc源码(三)——XmlWebApplicationContext初始化的整体过程
- Spring源码学习-容器初始化之FileSystemXmlApplicationContext(二)路径格式及解析方式(上) 推荐
- Spring之SpringMVC(源码)启动初始化过程分析