美文网首页Tomcat
Tomcat之请求在容器内执行源码分析

Tomcat之请求在容器内执行源码分析

作者: loveFXX | 来源:发表于2020-05-23 21:15 被阅读0次

    请求在容器内的调用


    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实现

    相关文章

      网友评论

        本文标题:Tomcat之请求在容器内执行源码分析

        本文链接:https://www.haomeiwen.com/subject/gdakahtx.html