目标项目先部署到Tomcat上
1、将项目打包
选项中有web application exploded,这个是以文件夹形式(War Exploded)发布项目,选择这个,发布项目时就会自动生成文件夹在指定的output directory,
如果选web application archive,就是war包形式,每次都会重新打包全部的,将项目打成一个war包在指定位置;
2、Tomcat上添加要发布的项目
如果没有做第二步则会报如下的404
原始服务器没有找到目标资源的当前表示,或者不愿意透露存在该目标资源
如果配置完毕,那么就可以启动Tomcat了。
重要时机点分析如下
断点准备
1、先在要执行的业务逻辑处打断点,当断点停在此处,则结合调用栈进行分析
2、在页面处也打上断点,看什么时候调过来
打完断点,然后就可以debug启动
1)Handler方法的执行时机剖析
发送一个请求,通过调用栈查看它调用流程
其实是先调整到jsp页面的,放行后跳到后台
通过调用栈看业务逻辑执行的时机点
从下面一直往上看,发现最后是通过doDispathch去执行后续Handler的事情,也就是doDispathch是核心的核心。doDispathch方法中的1052行代码完成handler方法的调用
思考:
1、调用ha.handle就能返回ModelAndView,那么传入的参数mappedHandler.getHandler()哪里来的
2、用ha去调用,那么ha又是从哪里来的
3、根据上面两个疑问,往上找代码,
通过调用栈看页面渲染的时机点
重要的时机点找出来了,可以正向去看
在doDispatch打上断点,重新请求,看其核心步骤
1、调用getHandler方法返回的是执行链
执行链包含着拦截器
2、调用getHandlerAdapter方法返回适配器
3、通过适配器的调用handle方法返回ModelAndView
执行链为参数,用返回的适配器去调用handle方法,返回ModelAndView
4、调用processDispatchResult去渲染视图
当调用processDispatchResult方法的时候,接下来就跳到页面了
说明是渲染页面的。
Spring MVC处理请求的大致流程(doDispatch方法核心步骤) :
1)调用getHandler() 获取到能够处理当前请求的执行链HandlerExecutionChain (Handler+拦截器)
如何去getHandler的?
2) 调用getHandlesAdapter(); 获取能够执行2) 中Handler的适配器。 如何去getHandlerAdapter的?
3) 适配器调用Hapdler执行ha.handle(总会返回一个ModelAndView对象),而且执行链也为参数哦
4) 调用processDispatchResult() 方法完成视图渲染跳转,执行这个方法会跳到页面的哦
2)getHandler方法的分析
在getHandler方法上打个断点,重新请求进去
通过遍历获取数据并封装执行链
如何在刚进来的代码看重点呢?
把拦截器添加到执行链中
到此,也就清晰知道getHandler方法返回执行链的流程了。
3)getHandlerAdapter方法的分析
调用getHandlerAdapter方法返回适配器,进去看看其逻辑
遍历处理器适配器
发现它直接返回了。到此也就知道他适配器的底层执行逻辑。看请求的是属于三种类型的哪一种,就具体调用哪一种的方法,获取适配器。
4)什么时候进行组件初始化呢?
主要是加载相应的类形成对应的Bean对象
看onRefresh方法它执行链和时机点
打上断点,Debug启动,观察调用栈
看一下initHandlerMappings的初始化
就是将组件所对应的加载成Bean对象
if (this.detectAllHandlerMappings) 默认就是true的,找所有父类实现HandlerMappings的类
如果都找不到,就用默认实
默认加载的组件
在静态代码块加载
全局搜索DispatcherServlet.properties即可找到默认的配置了
其他的组件初始化也是差不多如同此流程。
看一下initMultipartResolver组件
多部件组件,用于文件上传的。这个名字是配置好的,它就会去按这个名字去查找。
5)handler方法执行细节剖析
里面还调用了一层,继续进入
先执行,根据返回结果的代码行来找目标代码行
一路走下来,这里调用invoke方法
先执行获取参数的数组
到里面去取值
6)processDispatchResult方法的执行细节剖析
通过参数出传入的,肯定不为空
先创建一个视图名,然后获取数据封装给视图名
看一下真正解析的方法
如果缓存是空的就自己创建
进入,看看如何创建的
判断是否是重定向、或者请求转发、根据不同的情况封装成不同的View实现
调用父类的重载方法,继续进入
这里看到了一个buildView,构建视图
调用父类的,继续进入
把逻辑视图名转为物理视图名
加上前缀后缀等信息
到此,一路返回
==================
返回了物理视图后,对物理视图进行渲染
需要渲染的数据放入进去
然后暴露一些东西出去
循环model的数据放入到request的域中
所以在前台jsp域中能通过request域来获取的原因。
分发,路径已经给他了,跳到对应的页面上去
这整个就是试图渲染的流程