Tomcat源码分析
本篇文章 会针对tomcat的实现原理,以及servletTomcat容器与运行机制,利用servlet的规范实现的一套web服务器,而spring mvc 也是 spring实现了servlet 的web应用程序。 tomcat这么流行 的Servlet Web容器,具有大量的配置可以扩展 良好的运行效果,在开发中不应该只是会用,更重要的是对原理以及实现方式的理解,也许最后你也能写出很好的一个t
前言
本篇文章 会针对tomcat的实现原理,以及servlet Tomcat容器与运行机制,利用servlet的规范实现的一套web服务器,而spring mvc 也是 spring实现了servlet 的web应用程序。 tomcat这么流行 的Servlet Web容器,具有大量的配置可以扩展 良好的运行效果,在开发中不应该只是会用,更重要的是对原理以及实现方式的理解,也许最后你也能写出很好的一个tomcat框架,也是为什么去研究他的原因。
Tomcat介绍
Apache Tomcat®软件是Jakarta Servlet,Jakarta Server Pages,Jakarta Expression Language,Jakarta WebSocket,Jakarta Annotations和Jakarta Authentication规范的开源实现。这些规范是 Jakarta EE 平台的一部分.
Jakarta EE 平台是 Java EE 平台的演变。Tomcat 10 及更高版本实现了作为 Jakarta EE 的一部分开发的规范。Tomcat 9 及更早版本实现了作为 Java EE 的一部分开发的规范。
在9.0.40 根据 不同的安装包去下载不同的安装包。
下载过后 的关键目录
在bin目录中 包括的 bat 文件启动的 对应的 win版本的启动以及 linux的启动方式。
我们要开发中间件 都参考这种形式去开发就可以了。
config目录 这里面 的web.xml 以及 catalina.policy 设置运行jvm的 权限 等参数 都放到 这里面。
在 policy 中 包括了 shutdown 以及 juc日志等。
执行器 线程池,重新定义 数量等等。
对于jsp 的请求访问 处理 方式等。
在 web.xml中可以 设置的json,能够解读 对应的映射地方 在 tomcat中 自动给我们设置好的。
tomcat-users.xml 配置相关的权限等。配置方式 在 文件上 都有一个例子给我们使用。
然后以及经常使用的地方也就是 webapps 启动 到 对应的 项目上
在使用上可以配置 对应 的访问地址,这都是tomcat提供给我们进行项目地址
jmx是jdk给我们提供的管理插件的功能,
部署方式
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
<Context path="/Demo1" docBase="d:/Demo1" reloadable="true"></Context>
</Host>
<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="d:/Demo1" reloadable="true"></Context>
Tomcat源码下载与构建
需要添加 环境变量这些。
Tomcat容器与运行机制
赋值catlina.bat 调用格式, start参数, 其实 start.bat 调用时,都是调用的catalina.bat,这个可以在脚本中就可以看出来
在tomcat中 的启动类
对于参数来说, 传入的参数 第一个参数就是 start
启动 最终底层 都调用到了bootstarp
做了初始化的操作 init
继续 加载 catalina
紧接着 继续下去
根据不同的 命令 选择 不同的方式进行方式。
然后继续下去 就是 初始化 命名 ,
设置命名空间等等。 初始化的factroy
解析 对应的serverxml 并设置 home 的file
创建 摘要器等 初始化部分。
- 1. 启动类加载器
- 2. 加载启动类
- 3. Bootstrap的守护线程初始化方法执行完成
1. Catalina.setAwait(true)
2. Catalina.load()
- 1. initDirs()方法设置属性值,例如
catalina.home = D:/tomcat
catalina.base == catalina.home
- 2. initNaming初始化命名
setProperty ( javax . naming . Context . INITIAL_CONTEXT_FACTORY ,org . apache . naming . java . javaURLContextFactory -> default )
- 3. createStartDigester()
- 4. 加载server.xml并解析
- 5. 日志输出处理
- 6. 调用所有的组件初始化方法,确保每个对象都注册到了JMX代理上
3. Catalina.start()
1. 启动NamingContext绑定所有JNDI引用到NamingContext中
2. 启动<Server>标签下的service
3. 通过Service启动StandardHost
- 配置ErrorReportValve以对不同的HTTP错误代码执行正确的HTML输出
- 启动管道中的阀门Valve(至少是ErrorReportValve)
- 配置StandardHostValve
- 启动HostConfig组件
4. Tomcat 在HTTP端口上开始接受请求
5. Servlet类调用
Tomcat处理请求的过程
- 1. 用户点击网页内容,请求被发送到本机端口8080,被在那里监听的Coyote HTTP/1.1 Connector获得。
- 2. Connector把该请求交给它所在的Service的Engine来处理,并等待Engine的回应。
- 3. Engine获得请求localhost/test/index.jsp,匹配所有的虚拟主机Host。
- 4. Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机),名为localhost的Host获得请求/test/index.jsp,匹配它所拥有的所有的 Context。Host匹配到路径为/test的Context(如果匹配不到就把该请求交给路径名为“ ”的Context 去处理)。 path=“/test”的Context获得请求/index.jsp,在它的mapping table中寻找出对应的 Servlet。Context匹配到URL PATTERN为*.jsp的Servlet,对应于JspServlet类。
- 5. 构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet() 或doPost().执行业务逻辑、数据存储等程序。
- 6. Context把执行完之后的HttpServletResponse对象返回给Host。
- 7. Host把HttpServletResponse对象返回给Engine。
- 8. Engine把HttpServletResponse对象返回Connector。
- 9. 1Connector把HttpServletResponse对象返回给客户Browser。
Tomcat中的组件
public class Main {
public static void main(String[] args) {
Main main = new Main();
System.out.println(main.getClass().getClassLoader());
System.out.println(main.getClass().getClassLoader().getParent());
System.out.println(main.getClass().getClassLoader().getParent().getParent());
}
}
双亲委派机制
- 如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行。
- 如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器。
- 如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式。
双亲委派优势
- 避免重复加载
- 安全-防止核心API库被篡改
Catalina
主要的功能包括接收请求,处理请求,返回结果,这些具体的实现是在catalina里面的子容器里面。
Lifecycle
更多推荐
所有评论(0)