原文连接:http://simpleframework.net/blog/v/16313.html
最近在看Tomcat的源码,下面用博客记下看源码的一些心得。
Tomcat是从org.apache.catalina.startup.Bootstrap#main()开始启动. 大致分为三个步骤,即init、load和start。代码如下:
Java代码
public static void main(String args[]) {
try {
// Attempt to load JMX class
new ObjectName("test:foo=bar");
} catch (Throwable t) {
System.out.println(JMX_ERROR_MESSAGE);
try {
// Give users some time to read the message before exiting
Thread.sleep(5000);
} catch (Exception ex) {
}
return;
}
if (daemon == null) {
daemon = new Bootstrap();
try {
daemon.init(); ★1
} catch (Throwable t) {
t.printStackTrace();
return;
}
}
try {
String command = "start";
if (args.length > 0) {
command = args[args.length - 1];
}
if (command.equals("startd")) {
args[0] = "start";
daemon.load(args);
daemon.start();
} else if (command.equals("stopd")) {
args[0] = "stop";
daemon.stop();
} else if (command.equals("start")) {
daemon.setAwait(true);
daemon.load(args); ★2
// 反射调用Catalina的start方法
daemon.start(); ★3
} else if (command.equals("stop")) {
daemon.stopServer(args);
}
} catch (Throwable t) {
t.printStackTrace();
}
}
从以上可以很清楚的看出tomcat是通过参数的不同进行相应的命令调用。
★1 启动、初始化(加载类)
启动之前要进行相应的init()初始化,进行相应的环境设置以及包的加,以下是init()方法。(org.apache.catalina.startup.Bootstrap.init())
Java代码
public void init()
throws Exception
{
setCatalinaHome();//设置Catalina安装目录
setCatalinaBase();//设置Catalina工作目录
initClassLoaders();//加载jar包
// 将classload设置进线程,以便我们使用时进行调用
Thread.currentThread().
setContextClassLoader(catalinaLoader);
SecurityClassLoad.securityClassLoad(catalinaLoader);
// 加载启动类和调用它的process方法
if (log.isDebugEnabled())
log.debug("Loading startup class");
Class startupClass =
catalinaLoader.loadClass
("org.apache.catalina.startup.Catalina");
Object startupInstance = startupClass.newInstance();
// 设置共享扩张类加载器
if (log.isDebugEnabled())
log.debug("Setting startup class properties");
String methodName = "setParentClassLoader";
Class paramTypes[] = new Class[1];
paramTypes[0] = Class.forName("java.lang.ClassLoader");
Object paramValues[] = new Object[1];
paramValues[0] = sharedLoader;
Method method =
startupInstance.getClass().getMethod(methodName,
paramTypes);
method.invoke(startupInstance, paramValues);
catalinaDaemon = startupInstance;
}
在加载jar的时候,需要初始化classloader,代码如下:(org.apache.catalina.startup.Bootstrap)
Java代码
private void initClassLoaders() {
try {
commonLoader = createClassLoader("common", null);
catalinaLoader= createClassLoader("server", commonLoader);
sharedLoader = createClassLoader("shared", commonLoader);
} catch (Throwable t) {
log.error("Class loader creation threw exception", t);
System.exit(1);
}
}
tomcat中的加载方式是:
|-------commonLoader (common)-> System Loader
|-------sharedLoader (shared)-> commonLoader -> System Loader
|-------catalinaLoader(server) -> commonLoader -> System Loader
Common是公共类加载器,负责加载tomcat内部和web应用程序可以看到的类(%CATALINA_HOME%/bin/common下的jar文件),Catalina负责加载的是tomcat内部使用的类(%CATALINA_HOME%/server下的jar文件),这些类对web应用程序不可见。Shared负责加载的是web应用程序之间共享的类(%CATALINA_BASE%/shared下的jar文件),这些类对于tomcat内部是不可见的。如果%CATALINA_HOME%/conf/catalina.Properties中没有指定Common的搜索路径,则用当前的类的类加载器即系统类加载器作为Common。
★2 装载相应的资源
下面主要讲解tomcat的load()方法。下图是Catalina.load方法的时序图。
(1) 从上面的时序图可以看出首先调用Catalina类的load()方法,具体代码如下:
(org.apache.catalina.startup.Catalina)。
Java代码
public void load() {
initDirs();
// Before digester - it may be needed
initNaming();
// Create and execute our Digester
Digester digester = createStartDigester();
try {
inputSource.setByteStream(inputStream);
digester.push(this);
digester.parse(inputSource); //对server.xml进行解析
inputStream.close();
}
......
// Start the new server
if (server instanceof Lifecycle) {
try {
server.initialize(); //server初始化工作
} catch (LifecycleException e) {
log.error("Catalina.start", e);
}
}
long t2 = System.currentTimeMillis();
log.info("Initialization processed in " + (t2 - t1) + " ms");
}
(2) 在上面的load()方法中需要进行server的初始化工作,下图为Catalina.initialize的时序图,从图中可以看出server初始化所完成的工作。
至此,load方法结束,初期化的工作结束,下面开始进入start方法。
★3 容器启动
容器启动时,会调用Catalina.start(),下图为它的时序图。从图中可以看出StandardService的start方法被调用后会分别对Container和Connector进行start方法的调用。
1. Bootstrap调用Catalina的start方法
Catalina.start()方法(org.apache.catalina.startup.Catalina.start())
Java代码
public void start() {
// 启动server
if (server instanceof Lifecycle) {
try {
((Lifecycle) server).start();
......
}
2. Catalina调用StandardServer的start方法
StandardServer.start() (org.apache.catalina.core.StandardServer.start() )
Java代码
public void start() throws LifecycleException {
synchronized (services) {
for (int i = 0; i < services.length; i++) {
if (services[i] instanceof Lifecycle)
((Lifecycle) services[i]).start();
}
}
3. StandardServer调用StandardService的start方法
Java代码
org.apache.catalina.core.StandardService.start() )
public void start() throws LifecycleException {
if (container != null) {
synchronized (container) {
if (container instanceof Lifecycle) {
// standardEngine的启动
((Lifecycle) container).start();
}
}
//两个connector的启动,8080和8009
synchronized (connectors) {
for (int i = 0; i < connectors.length; i++) {
if (connectors[i] instanceof Lifecycle)
((Lifecycle) connectors[i]).start();
}
}
}
以上StandardService.start()方法主要实现了两个功能,standardEngine的启动和connector的启动,下面分别来介绍。
分享到:
相关推荐
它的版本号"9.0.0.M22"表明这是一个维护版本M22,属于Tomcat 9.0系列。Apache服务器通常用于静态内容的托管,而Tomcat则是处理动态内容,如Java JSP、Servlet等。将两者结合使用,可以构建一个功能强大的全栈Web服务...
Tomcat是Apache软件基金会Jakarta项目的一部分,它遵循Apache Software License v2.0发布,因此是免费且开放源码的。Tomcat的轻量级特性使其成为小型到中型应用的理想选择,尤其是在资源有限的环境中。 标签“java ...
【标题】中的“管理系统系列”指的是一个集合了多种管理系统的项目,这可能包括不同领域的应用,如企业资源规划(ERP)、客户关系管理(CRM)或供应链管理(SCM)。在这个特定的例子中,我们关注的是“图书管理系统...
10.0.1是OpenCms的一个版本,通常包含一系列改进和新功能。 2. **核心组件** - **内容管理**:OpenCms提供了强大的内容创建、审批和发布流程,包括模板驱动的内容生成,支持XML存储内容。 - **工作流**:系统内置...
- **起步依赖**:通过`spring-boot-starter`模块,引入一系列预配置的依赖,如`spring-boot-starter-web`用于web开发。 2. **项目结构解析**: - **主程序**:通常包含一个启动类,使用`@SpringBootApplication`...
这个版本可能是该系列的一个稳定版,具有一定的安全性和性能优化。 【描述】中的信息强调了学习Tomcat 7.0.67的源码分析,这对于深入理解其工作原理至关重要。在下载并解压源码后,用户需要在主目录下创建`lib`、`...
在IT行业中,Shell脚本是Linux和Unix系统中不可或缺的一部分,它是一种强大的自动化工具,能够帮助用户执行一系列命令,简化日常任务。这个压缩包文件包含了关于shell脚本编写和源码的相关资料,非常适合初学者和有...
本篇文章将深入探讨一个名为"library"的J2EE项目源码,该源码分享为我们提供了学习和理解J2EE核心概念的宝贵资源。 首先,我们来看看J2EE的核心组件。J2EE包含以下几个主要部分: 1. **Servlet**:Servlet是Java ...
- 简化Maven配置:Spring Boot提供了一系列starter POMs,用于简化Maven依赖管理。 2. **Java语言**: - **简介**:Java是一种面向对象的编程语言,广泛应用于Web开发、移动应用开发等多个领域。 - **特点**: ...
在源码中,`run()`方法会进行一系列的初始化工作,包括扫描启动类、加载配置、初始化Bean定义等。 配置文件是SpringBoot的另一个关键部分。SpringBoot支持两种主要的配置文件:`application.properties`和`...
批处理则通常指的是在计算机程序设计中,一次性处理大量数据或执行一系列命令的操作。 在IT行业中,这三者之间的结合可能涉及到Web应用的开发和部署,以及数据库管理和优化。Tomcat是Apache软件基金会的项目,用于...
### Java Web招聘系统的SSH框架与MyEclipse源码解析 #### 一、Java Web技术概述 Java Web技术是构建Web应用程序的重要工具之一,它利用Java编程语言开发网站应用。Java Web技术的优势在于其跨平台性、安全性以及...
- **JSTL(JSP Standard Tag Library)**:标准标签库,提供了一系列预定义的标签,用于处理常见任务,如循环、条件判断等。 4. **安全性与优化** - **防止SQL注入**:使用预编译语句或ORM框架(如Hibernate)来...
本项目是一个针对地方美食分享的在线平台,专为学生课设或毕业设计而设计,采用现代化的Web开发技术栈——SpringBoot和Vue.js。通过这个系统,用户可以浏览、分享和评论各地美食,促进美食文化的交流与传播。下面将...
3. **起步依赖**:提供了一系列“starter”依赖,帮助开发者快速引入所需功能模块,如数据访问、Web服务等。 4. **自动配置**:根据引入的依赖自动配置相关组件,如Spring Data JPA、Spring MVC等。 **数据库MySQL*...
Pudn.com是一个资源分享网站,可能是该源码的下载来源。 2. "极度学习整站系统_jsp" - 这可能是一个JSP应用的主目录或文件,包含整个网站系统的源代码。"极度学习"可能是指这个系统专注于教育或学习相关的功能,例如...
【方立勋 JavaWeb 源码】是一个与JavaWeb开发相关的代码集合,可能是由知名讲师或开发者方立勋创建并分享的。JavaWeb是指使用Java技术进行Web应用程序开发的一系列技术和框架的总称,包括Servlet、JSP、JavaServer ...
7. **论坛功能**:JForum包含了一系列常见论坛功能,如用户注册、登录、发帖、回帖、私信、搜索、用户组、权限控制、邮件通知等,为用户提供完整的社区交流体验。 8. **性能优化**:JForum在设计时就考虑到了性能...
3. 订餐全流程管理:从菜单展示、选择菜品、下单支付到订单处理、配送跟踪,这一系列流程都需要被完整地实现。Hibernate将菜品、订单等实体对象与数据库表进行映射,方便数据的持久化存储。 4. 图书管理:虽然标题...
Java环保服务网源码含开发文档是一套基于Java技术实现的网站系统,旨在提供一系列环保相关的服务,包括建筑设计、房屋装修装潢设计、汽车修理、专业园林设计、专业公共广场设计,以及用户互动功能如留言和聊天。...