跟踪Spring MVC的请求
在Spring MVC中,DispatcherServlet就是前端控制器;
DispatcherServlet的任务就是将请求发送给Spring MVC控制器,在典型的应用程序中可能会有多个控制器,DispatcherServlet需要知道应该将请求发送给哪个控制器,所以DispatcherServlet会查询一个或多个处理器映射来确定请求的下一站在哪。处理器映射会根据请求锁携带的URL信息来进行决策。
到了控制器,请求会卸下其负载并耐心等待控制器处理这些信息,实际上控制器本身只处理很少甚至不处理工作,而是将业务逻辑委托给一个或多个服务对象进行处理。
控制器完成逻辑处理后,通常会产生一些信息,这些信息需要返回给用户并在浏览器上显示,这些信息被称为模型。为了更好地用户体验,信息需要发送一个视图,通常是JSP。控制器所做的最后一件事就是将模型数据打包,然后将请求连通模型和视图名发送回DispatcherServlet。
DispatcherServlet将会使用视图解析器(view resolver)来将逻辑视图名匹配为一个特定的视图实现。
请求的最后一站是视图的实现,在这里它交付模型数据,请求的任务就完成了,视图将使用模型数据渲染输出,这个输出会通过响应对象传递给客户端。
搭建Spring MVC
配置DispatcherServlet
spring容器的启动加载流程
- 首先解析配置文件spring.xml,把其中的
<bean>解析为BeanDefinition对象并存入BeanFactory;把BeanDefinition中的定义读取到一个map集合中管理起来了,但还没有创建bean对象;
<bean id="" calss="" init-method="" destroy-method="" scope="" lazy-init="">
BeanFactory使用 bean 工厂根据BeanDefinition来创建受管理的对象;bean工厂的后处理器;
接下来由beanFactory来创建每个类对应的单例对象,利用了反射根据类名创建实例对象(调用构造方法、初始化方法);
执行bean的后处理器,其中有两个方法,会在bean的初始化前后被调用;将对象结果存入beanFactory的singletonObjects这样的map集合里;
执行依赖注入,先把所有对象创建好都放入map集合,主要是为了解决循环引用问题;
先把A创建了放入map,再把B创建好放入map,给A进行依赖注入B时,从map中获取B对象赋值给A中的B属性;当执行
容器.getBean(类名.class)根据bean的id作为key,进入singletonObjects获取值,返回结果就是实例对象;
注意:
Aop中的代理对象是在bean后处理器中的init方法后执行的方法产生的;
mapperScannerConfigurer去
SpringMvc的执行流程
- 所有请求通过匹配 / 路径进入了Dispatcherservlet
- multipartResolver 是处理文件上传的表单解析器;
- localResolver提供国际化功能;
- handlerMapping 处理浏览器请求路径,找到对应控制器中RequestMapping注解的哪个方法;
- handlerAdapter 处理适配器:真正去执行控制器中的方法;
- handlerExceptionResolver (异常解析器)负责处理控制器方法中的异常
@ExceptionHandler - viewNameTranslator用来解析视图名称,将方法返回的字符串对应视图的名称;
- viewResolver 视图解析器,把视图的字符串名名称解析为真正的视图对象;
- themeResolver
- flashMapManager
- 进入DispatchServlet之后,然后会进入doDispatch方法,来执行请求的分发;
//HandlerExcutionChain由handlermapping生成
HandlerExcutionChain mapperHandler=getHandler(prodessedRequest); //
进入了handlermapping进行路径匹配,路径匹配结束返回handlerexcutionchain执行链;
执行链里会依次调用拦截器的preHandler
进入handlerAdapter,由它来调用控制器,回到执行链;
handlerAdapter有一个返回结果ModelAndView返回给doDispatch方法;
doDispatch里ModelAndView再被视图解析器解析,获得一个视图对象View;
View 对象调用render方法,负责产生一个响应结果返回给浏览器;
执行链里会反序调用拦截器中的afterComletion;
生成的响应结果,返回给浏览器;
HandlerExcutionChain(处理适配器)拦截器
先调用拦截器1的 prehandler 在调用拦截器2的prehandler方法 …所有的拦截器方法调用完,在进入handlerAdapter;HandlerAdapter
执行控制器方法,等控制器方法执行完之后再返回拦截器,执行每个拦截器中的posthandler方法;