在很多高端开发岗位,面试官或多或少都会被要求研究一些常用的中间件源码。这是因为所有的秘密都隐藏在源代码中。阅读源码可以让我们对框架或中间件有更深入的了解,也可以从源码研究中获得一些优秀的设计方法。而我们有那么多的中间件和源码,应该从哪里入手呢?事实上,大多数中间件或框架都有一些共同的部分,例如网络编程、多线程、反射和类加载等技术。所以如果深入研究一两个中间件价格,再回头看看其他中间件,那么就很容易理解其中使用的技术和原理。Tomcat作为一个老牌的WEB端框架,无论是整体的架构设计,还是对内部一些技术的灵活运用,都值得一看。在学习框架的时候,我一般会对框架有一个整体的了解。从整体上了解它是如何工作的,然后再深入其中的一部分,会事半功倍。整体架构我们要了解一个框架,首先要了解它是干什么的。我们都知道Tomcat是用来处理连接的Socket请求的。那么Tomcat就会有两个功能:外部处理连接,将接收到的字节流转换成你想要的Request和Response对象,内部处理Servlet,将相应的Request请求分发给相应的Servlet。那么我们的整体骨架就出来了。Tomcat实际上分为两部分,一部分是处理外部连接的连接器(Connnector)和管理内部Servlet的容器??(Container)。大致关系图如下:最外层框架代表一个Tomcat服务,一个Tomcat服务可以对应多个Service。每个服务都有连接器和容器。这些对应关系也可以在Tomcat目录配置文件中的server.xml中看到。这里我放在配置里文件中的一些内容已被删除和简化。这里我们可以看到一个连接器其实就是一个Connector。一个Service中可以有多个connector,container其实对应一个Engine。Tomcat的整体架构就是这么一个对应。接下来,我们简单介绍下connector的整体架构和container的整体架构。Connector我们可以看到上图中连接器传递给容器的是一个ServletRequest对象,而容器传递给连接器的是一个ServletResponse对象。这些在网络传输的时候肯定是不行的,因为网络传输的时候传输的是字节流。因此,关于连接器的功能需求,我们大概可以总结出以下几点。Socket连接读取请求网络中的字节流,根据相应的协议(Http/AJP)解析字节流,生成统一的TomcatRequest对象。将Tomcat请求传递给容器并返回Tomcat响应对象。将Tomcat响应对象转换为字节。流将字节流返回给客户端。其实上面的细分可以概括为以下三点:网络通信应用层协议的分析,Tomcat的Request/Response和ServletRequest/ServletResponse对象的转换,它在Tomcat中也用到了这三个。一个实现上面三个功能的类,分别对应下面的EndPointProcessorAdapter如果用图来表示他们的关系,就是这样一个container容器。小服务程序。那么容器是如何设计的呢?Tomcat的容器设计其实就是使用了复合设计模式(如果你不知道复合设计模式,可以看看我之前的文章,学了无数东西——复合模式)。其实我们从Server.xml也可以看出关系。复制这里的代码我们只能看到容器中有两个模块,一个是顶层模块Engine,一个是Host,其实有两个模块,一个是Context对应我们webapp中的每个应用文件夹,每个文件夹对应一个Context,还有一个moduleWrapper对应我们Context中所有的servlet,Wrapper管理着访问关系和具体Servlet的对应关系。如图所示,是这样的。Tomcat中容器的所有模块都实现了Container接口,组合模式的意义在于让用户在使用单个对象和组合对象时保持一致,即无论添加多少个Context,其使用就是找它下面的Servlet,不管添加了多少Hosts也是找下面的Servlet。容器中设计了这么多模块,Tomcat如何找到对应的Servlet来处理一个请求呢?让我们举一个最简单的例子来说明如何定位请求。我们在我们本地的应用上启动了一个Tomcat,我们在webapp下有一个buxuewushu部署的应用。我们在浏览器输入http://localhost:8080/buxuewushu/add.do如何找到对应的Servlet呢?当我们启动Tomcat时,连接器会初始化并监听配置的端口号。这里我们配置了8080端口对应的协议为HTTP。请求被发送到本机的8080端口,由在那里监听的HTTP/1.1连接器Connector获取地址http://localhost:8080/buxuewushu/add。匹配他下面的host来匹配名为localhost的主机(即使此时请求的是具体的ip,并且没有配置对应的Host,也会交给名为localhost的主机处理,因为是默认的host)Host匹配进入路径为/buxuewushu的Context,即找到webapp下对应的文件夹。Context匹配URL规则为*.do的servlet,对应调用某个Servlet类的doGet或doPost方法。Servlet执行完毕后,将对象返回给ContextContext返回给HostHost返回给EngineEngine返回给ConnectorConnectorConnector将对象解析成字节流发送给client作者的Property。商业转载请联系作者授权,非商业转载请注明出处。