前一篇博客,我总结了Tomcat对于生命周期组件的管理。在了解了容器的启动以后,咱们开始剖析它的内部运行机制。今天咱们来分析一下Tomcat如何处理Request。Socket做为网络通讯的基础也是Request和Response的底层实现,有过Socket使用经验的读者必定不会对下面的伪代码陌生:apache
// Java伪代码 ... while(true) { Socket soc = ServerSocket.accept(); // 监听并阻塞 new Thread(new Runnable() { // 开辟新的线程处理Socket inputStream(soc); // 读取Socket中的数据 outputStream(soc); // 写入数据 }); } ...
1、从Socket到Request设计模式
Tomcat容器对Socket的处理思路与以上伪代码基本一致,只是更加复杂。下图展现了从Tomcat启动到Socket到来后,主要类的调动过程(虚线箭头表示有新的线程启动):网络
Acceptor是定义在JIoEndpoint中的内部类实现了Runnable接口。在run方法中定义了循环语句while (running){...}重点是ServerSocketFactory获取监听端口(默认8080)上的Socket请求app
Socket socket = null; try { // Accept the next incoming connection from the server // socket socket = serverSocketFactory.acceptSocket(serverSocket); ...
而后,这个Socket对象会被封装成SocketWrapper对象并交给给JIoEndpoint的另外一个内部类SocketProcessor处理。socket
protected boolean processSocket(Socket socket) { // Process the request from this socket try { SocketWrapper<Socket> wrapper = new SocketWrapper<Socket>(socket); wrapper.setKeepAliveLeft(getMaxKeepAliveRequests()); wrapper.setSecure(isSSLEnabled()); ...
一直到AbstractHttp11Processor.process方法,咱们第一次见到了Request的身影。不过此时的Request其实是org.apache.coyote.Request,它是Tomcat内部的定义类而且被final修饰。在CoyoteAdapter.service方法中,它又被处理成:org.apache.catalina.connector.Request,它继承了HttpServletRequest。直到这时,从Socket到Request才真正完成。函数
2、Pipeline、FilterChain以及设计模式this
ContainerBase是Tomcat中的生命周期组件。它包含了4个标准的实现类:StandardContext、StandardEngine、StandardHost和StandardWrapper。每个Container对象都含有各自的Pipeline和Valve。spa
/** * The Pipeline object with which this Container is associated. */ protected Pipeline pipeline = new StandardPipeline(this); /** * Create a new StandardContext component with the default basic Valve. */ public StandardContext() { super(); pipeline.setBasic(new StandardContextValve()); ... } ...
它们经过Container的构造函数被初始化,并负责处理Request。每个Containner组件都实现了各自的invoke方法,具体的业务逻辑读者能够本身去分析。线程
通过4次invoke,Request会继续交给FilterChain(责任链模式的核心对象)处理。设计
ApplicationFilterChain filterChain = factory.createFilterChain(request, wrapper, servlet); try { if ((servlet != null) && (filterChain != null)) { if (context.getSwallowOutput()) { ... } else { if (request.isAsyncDispatching()) { ... } else if (comet) { ... } else { filterChain.doFilter(request.getRequest(), response.getResponse()); } } ...
通过多个Filter的处理,才会交到Servlet的手中。