Tomcat 请求流程

以NIO为例

1. NioEndpoint.Acceptor 阻塞处理 accept() 并把合适的socket 放置BlockingQueue

2.  NioEndpoint.Poller 从BlockingQueue拿socket,使用NIO的非阻塞方式 处理read(),把read()事件ready的socket交给线程池处理

3. read() http请求内容并包装request

4. 以request 的具体请求path 分别找到匹配的 host context wrapper(在没有配置load-on-startup时内含的servlet instance第一次访问时是null)

5. 分别从匹配的host context wrapper中拿出相应的处理流程 hostvalve contextvalve wrappervalve 依次去处理

6. wrappervalve这一步中需要先把servlet实例化(在还没有被实例化的情况下)

7. 找到request path匹配的所有filter+servlet 组成filterChain 然后调用filterChain

8. 在所有的filter的doFilter() 跑完后 调用servlet 的service() 

9. 返回结果写回 socket


JSP流程

主体流程与以上一样,有意思的是处理JSP的是的step 4是中的wrapper持有的instance是固定的JspServlet。主要说说JspServlet.Service()方法的流程

假使访问流程如下:

1)访问JSP

2)修改JSP

3)再次访问JSP(以下展示此次流程)

1. 正如servlet的路由表value是使用wrapper(StandardWrapper)来做包装,同样在JspServlet中的路由表也不是直接指向JSP的实例对象,也是类似的wrapper(JspServletWrapper)

2. 通过url找到对应的JspServletWrapper

3. JspServletWrapper中会经过:尝试编译,获取实例,调用JSP编译后的class文件的_jspService()方法

1). 查看是否打开JSP动态编译||是否第一次加载JSP。如果是则首先检测该JSP有没有修改。如果有,则使用JDTCompiler编译JSP为class。

2). 调用原先的JSP对应servlet的destroy()方法

3). 如果1 中进行过重新编译,则需要使用新的classloader去加载JSP对应的class文件并进行实例化,最后把JspServletWrapper的theServlet赋值为最新的实例

4). 调用JSP对应class文件的_jspService()方法





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值