一、Tomcat接口
server.xml配置文件讲解
<?xml version='1.0' encoding='utf-8'?> <Server port="8005" shutdown="SHUTDOWN"> <!--停止端口号 --> <Listener className="org.apache.catalina.startup.VersionLoggerListener" /> <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on"/> <Listener className="org.apache.catalina.core.JasperListener" /> <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<GlobalNamingResources> <Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" /> </GlobalNamingResources>
<Service name="Catalina">
<!--两个链接,不同协议不同端口号--> <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost"> <Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/> </Realm>
<!--webapps对应着文件夹webapps项目部署--> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs" prefix="localhost_access_log."
suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" /> </Host> </Engine>
</Service>
</Server>
server.xml图示
server.xml模型图:

Tomcat架构小结(面试回答这个):

[1] Connector中具体用ProtocolHandler来处理请求的,不同的ProtocolHandler代表不同的连接类型(如 Http11Protocol使用普通的Socket来连接,Http11NioProtocol使用NioSocket连接)。
[2] Endpoint用于处理底层Socket的网络连接,用来实现TCP/IP协议 。
Acceptor:用于监听和接受请求。
Handler:请求的初步处理。并且调用Processor。
AsyncTimeout:检查异步的Request请求是否超时。
[3] Processor用于将Endpoint接收到的Socket封装成Request,用来实现HTTP协议。
[4] Adapter用于将Request交给Container进行具体处理,即将请求适配到Servlet容器。
面试进阶——Container架构:
Container就是一个Engine。Container用于封装和管理Servlet,以及具体处理Request请求。
[1] Engine:Container(容器/引擎),用来管理多个站点,一个Service最多只能有一个Engine.
[2] Host: 虚拟主机,一个Container可以有多个虚拟主机。
[3] Context: 一个应用程序,就是我们平时开发的一个项目,或者说一套web引用程序。
[4] Wrapper: 用来包装Servlet,每一个Wraper都包装着一个Servlet。

二、类加载器流程
JVM类加载机制:详情
Tomcat类加载:
Bootstrap 引导类加载器 :加载JVM启动所需的类,以及标准扩展类(位于jre/lib/ext下),将JVM前三个类加载器概括到一起了。
System 系统类加载器 :加载tomcat启动的类,比如bootstrap.jar,通常在catalina.bat或者catalina.sh中指定。位于CATALINA_HOME/bin下。
Common 通用类加载器:加载tomcat使用以及应用通用的一些类,位于CATALINA_HOME/lib下,比如servlet-api.jar。
webapp应用类加载器:每个应用在部署后,都会创建一个唯一的类加载器。该类加载器会加载位于 WEB-INF/lib下的jar文件中的class和 WEB-INF/classes下的class文件。
JSP类加载器 :tomcat会为每一个JSP创建一个类加载器。
【加载流程】
1 使用bootstrap引导类加载器加载 JVM基本类和扩展类
2 使用system系统类加载器加载 tomcat启动的类
3 使用应用类加载器在WEB-INF/classes中加载
4 使用应用类加载器在WEB-INF/lib中加载
5 使用common类加载器在CATALINA_HOME/lib中加载
问题1:为什么tomcat要给每个应用设置一个独立的类加载器
一个web容器可能需要部署两个应用程序,不同的应用程序可能会依赖同一个第三方类库的不同版本,不能要求同一 个类库在同一个服务器只有一份,因此要保证每个应用程序的类库都是独立的,保证相互隔离。例如项目1使用spring5.0,项目2使用spring5.1,两项目具有相同的类,当项目1进行了加载之后,项目二如果发现类已经加载过了就不会再进行加载。
问题2:为什么要给每个jsp文件设置一个独立的类加载器
web容器要支持jsp的修改,我们知道,jsp文件最终也是要编译成class文件才能在虚拟机中运行,但程序运行后修改jsp已经是司空见惯的事情。 所以,web容器需要支持 jsp 修改后不用重启。
问题3:tomcat是否违背了双亲委派模型
是的,违背了。tomcat 为了实现隔离性,没有遵守这个约定,每个webappClassLoader加载自己的目录下的class 文件,不会传递给父类加载器。