How Tomcat works 11: StandardWrapper容器

    1. Http request处理时序图
    
    2. StandardContext和StandardWrapper的构造函数:      

  Public StandardContext() {
            super();
            pipeline.setBasic(new StandardContextValve());
            namingResources.setContainer(this);
        }
        public StandardWrapper() {
            super();
            pipeline.setBasic(new StandardWrapperValve());
        }


    3. StandardWrapper的功能
    (1)加载servlet,分配servlet实例。调用service()方法留给了StandardWrapperValve【wrapperPipeline.basicValve】
    (2)StandardWrapper需要知道servlet类的全限定名
    (3)对于未实现SingleThreadModel的servlet, standardWrapper全局使用同一个StandardWrapper实例。对于实现了STM的servlet,standwrapper需要确保同时不能有两个线程调用一个servlet的service()方法。实际上会使用一个instancepool来为实现了STM的servlet存储实例。伪代码如下:
      

  public class SimpleWrapperValve {
            public void invoke(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                // ... 
                Servlet instance = null; //get an instance of servlet
                if(instance instanceof SingleThreadModel){
                    synchronized(instance) {
                        instance.service(request, response);
                    }
                }else {
                    instance.service(request, response);
                }
            }
        }


        
    (4)allocate方法同样需要区分STM servlet
    (5)load方法:
       判断是否JSP页面【若是,加载jspWrapper】->获取classLoader->classClass.newInstance()->判断是否ContainerServlet【servlet.setWrapper(this)】->fireInstanceEvent(BEFORE_INIT_EVENT, servlet)->servlet.init(facade)->fireInstanceEvent(AFTER_INIT_EVENT,servlet)->判断是否STM【若是,入实例pool】->return Servlet实例
    4. ServletConfig对象:
    (1)主要方法:getServletContext(), getName(), getInitParameter(),getInitParameterNames()
    5. Wrapper类
    (1)调用addChild()方法抛异常
    (2)可调用setParent(Context)
    6. StandardWrapperFacade类
    (1)需要隐藏许多StandardWrapper的内部实现,所以使用门面模式传入servlet.init()方法中。
    (2)UML
    
    7. StandardWrapperValue类
    (1)主要功能:执行所有servlet相关filters, 调用servlet的service方法
    (2)StandardWrapperVavle需要在invoke方法中实现:
        a. 获取一个包含了使用StandardWrapper.allocate分配的servlet实例
        b. 使用private createFilterChain()方法创建一个filter chain
        c. 调用filter chain的doFilter()方法,也包含调用servlet.service()方法
        d. 释放filter chain
        e. 调用wrapper的deallocate方法
        f. 如果servlet是永远不可用的,则调用wrapper的unload方法
    (3)代码:        

public void invoke(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //..
            if(!unavailable){
                servlet = wrapper.allocate(); 
            }
            // Acknowlege the request
            response.sendAcknowlegement();
            
            // Create the filter chain for the request
             ApplicationFilterChain filterChain = createFilterChain(request,servlet);
            filterChain.doFilter //也包含调用servlet.service方法
            filterChain.release()
            wrapper.deallowcate(servlet);
            if(wrapper.getAvailable() == Long.MAX_VALUE){
                wrapper.unload();
            }
        }


    8. BootStrap类  

  public static void main(String[] args) {
         System.setProperty("catalina.base",
         System.getProperty("user.dir"));
         Connector connector = new HttpConnector();
         Wrapper wrapper1 = new StandardWrapper();
         wrapper1.setName("Primitive");
         wrapper1.setServletClass("PrimitiveServlet");
         Wrapper wrapper2 = new StandardWrapper();
         wrapper2.setName("Modern");
         wrapper2.setServletClass("ModernServlet");
        Context context = new StandardContext();
        context.addChild(wrapper1);
        context.addChild(wrapper2);
        connector.setContainer(context);
        connector.initialize();
        connector.strart()
        context.start();
    }


    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
31-May-2023 21:55:15.359 信息 [http-nio-8080-exec-6] org.apache.catalina.core.ApplicationContext.log 将servlet[com.LdfandWh.servlet.CheckCodeServlet]标记为不可用 31-May-2023 21:55:15.359 严重 [http-nio-8080-exec-6] org.apache.catalina.core.StandardWrapperValve.invoke 分配异常的servlet [com.LdfandWh.servlet.CheckCodeServlet] java.lang.ClassNotFoundException: com.LdfandWh.servlet.CheckCodeServlet at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1365) at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1188) at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:539) at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:520) at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:150) at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1042) at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:761) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:135) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:748)
最新发布
06-01

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值