请求在容器内的调用
image.png
StandardEngine、StandardHost、StandardContext、StandardWrapper是容器的层级结构,以父子关系存在。
都继承了ContainerBase类,容器抽象类。包含parent、child、pipeline、realm等属性。pipeline中会设置Valve阀门,在请求流经容器执行时,会通过默认阀门传递到子容器对象。默认阀门StandardEngineValve、StandardHostValve、StandardContextValve、StandardWrapperValve。调用一层层阀门,在StandardWrapperValve类中会执行过滤链和自定义Servlet实现。
容器调用执行点
1、getService()
从连接对象connector获取StandardService对象
image.png
2、getContainer()
从service获取engine对象StandardEngine
image.png
3、getPipeline
从engine对象获取pipline
image.png
invoke方法
1、调用engine的阀门value的invoke方法
org.apache.catalina.core.StandardEngineValve#invoke
invoke.png
先获取请求的Host的实现类,之后调用Host的阀门value的invoke方法
image.png
其中StandardHost的孩子容器有6个,其中包含我们部署的testservlet项目。这六个就是webapps目录下的6个文件夹
image.png
2、调用Host的阀门value的invoke方法
StandardHost的pipeline有三个,其中first是AbstractAccessLogValve
image.png
①、先调用AbstractAccessLogValve的invoke方法
org.apache.catalina.valves.AbstractAccessLogValve#invoke
image.png
②、ErrorReportValve
org.apache.catalina.valves.ErrorReportValve#invoke
image.png
③、StandardHostValve
org.apache.catalina.core.StandardHostValve#invoke
image.png
3、调用Context的阀门value的invoke方法
首先获取Context对象
image.png
org.apache.catalina.core.ContainerBase#getPipeline
image.png
org.apache.catalina.core.StandardPipeline#getFirst
image.png
①、AuthenticatorBase
org.apache.catalina.authenticator.AuthenticatorBase#invoke
进行身份验证
image.png
image.png
realm得到的为null,jaspicProvider为null。调用下一个value的invoke方法
image.png
②、StandardContextValve
org.apache.catalina.core.StandardContextValve#invoke
包含META-INF则返回错误
image.png
获取当前请求Wrapper
image.png
发送确认、设置异步支持、继续调用invoke
image.png
4、调用Wrapper的阀门value的invoke方法
org.apache.catalina.core.StandardWrapperValve#invoke
①、初始化一些参数值,并获取wrap的父容器context
image.png
②、检查当前应用的context和servlet是否被标记为无效
image.png
③、为请求分配servlet对象
image.png
allocate
org.apache.catalina.core.StandardWrapper#allocate
根据singleThreadModel是否是单线程模式分配,不是单线程则会每次相同请求都会分配一个对象
image.png
image.png
loadServlet
org.apache.catalina.core.StandardWrapper#loadServlet
image.png
newInstance
org.apache.catalina.core.DefaultInstanceManager#newInstance(java.lang.String)
根据类构造方法创建对象
image.png
如果singleThreadModel=true单线程模型,那么将会从instancePool池中获取
image.png
④、获取过滤链filterChain
设置请求request属性,并获取过滤链filterChain,我们自定义的过滤器对象就会在这里获取到
image.png
⑤、过滤链doFilter执行
image.png
org.apache.catalina.core.ApplicationFilterChain#doFilter
image.png
org.apache.catalina.core.ApplicationFilterChain#internalDoFilter
这里是根据执行链的位置pos与包含数量n来判断执行
image.png
这里如果包含过滤链将会调用doFilter方法
image.png
⑥、在链的末尾调用servlet实例方法
image.png
调用到自定义对象HelloServlet实例方法
Globals.IS_SECURITY_ENABLED=false
image.png
这里会根据servlet协议实现类javax.servlet.http.HttpServlet#service调用
总结:
请求在容器内的调用核心就是通过Value阀门的不同容器级别不同实现类的invoke来传递调用的。
不同容器包含的默认实现Value阀门类。
在容器内的调用过程最后才调用到过滤链和自定义的servlet实现
网友评论