前面所叙述的tomcat启动中并没有webapps下边应用程序载入的内容,今天花了些时间在源代码中找到了一些相关的内容。
1. webapps下的应用程序的载入,要从Digester的HostRuleSet说起了:
当Digester解析XML到<Host>标签处时,有一个LifecycleListenerRule,它的begin方法如下所示。
通过这个方法,将一个HostConfig对象加入到了StandardHost的LifecycleListener中去。而这里就是加载webapps的基础之处。
随后,随着Tomcat的启动,开始调用Bootstrap#start()。在start()方法中进而调用了一系列的start()。这其中就包括StandardHost#start()。
StandardHost#start()中的前面很多句都没有包含载入webapps的行为,直到最后一句,就是调用了super.start(),也就是调用了ContainerBase#start()。其中这样一句引发了载入webapps的行为:lifecycle.fireLifecycleEvent(START_EVENT, null);
也就是通知START_EVENT给所有的LifecycleListener,其中就包括了前面提到的HostConfig。HostConfig#lifecycleEvent()就是实现事件处理的方法,如下所示:
这个方法的最后判断了当出现START_EVENT时要调用start()方法。
这个方法的最后调用了deployApps(),看名字就与部署应用程序有关系了,赶紧来看一下它写了什么。
这三个deploy*()方法分别负责载入三种形式的应用程序,这三个方法最后都会将应用程序的路径和对应的修改时间保存下来。方法太长就不详细介绍了。
1. webapps下的应用程序的载入,要从Digester的HostRuleSet说起了:
public void addRuleInstances(Digester digester) { digester.addObjectCreate(prefix + "Host", "org.apache.catalina.core.StandardHost", "className"); digester.addSetProperties(prefix + "Host"); digester.addRule(prefix + "Host", new CopyParentClassLoaderRule()); // 重要的就是这句,发现一个<Host>标签时,要实现LifecycleListenerRule digester.addRule(prefix + "Host", new LifecycleListenerRule( "org.apache.catalina.startup.HostConfig", "hostConfigClass")); digester.addSetNext(prefix + "Host", "addChild", "org.apache.catalina.Container"); digester.addCallMethod(prefix + "Host/Alias", "addAlias", 0); digester.addObjectCreate(prefix + "Host/Cluster", null, "className"); digester.addSetProperties(prefix + "Host/Cluster"); digester.addSetNext(prefix + "Host/Cluster", "setCluster", "org.apache.catalina.Cluster"); digester.addObjectCreate(prefix + "Host/Listener", null, "className"); digester.addSetProperties(prefix + "Host/Listener"); digester.addSetNext(prefix + "Host/Listener", "addLifecycleListener", "org.apache.catalina.LifecycleListener"); digester.addObjectCreate(prefix + "Host/Realm", null, "className"); digester.addSetProperties(prefix + "Host/Realm"); digester.addSetNext(prefix + "Host/Realm", "setRealm", "org.apache.catalina.Realm"); digester.addObjectCreate(prefix + "Host/Valve", null, "className"); digester.addSetProperties(prefix + "Host/Valve"); digester.addSetNext(prefix + "Host/Valve", "addValve", "org.apache.catalina.Valve"); }
当Digester解析XML到<Host>标签处时,有一个LifecycleListenerRule,它的begin方法如下所示。
public void begin(String namespace, String name, Attributes attributes) throws Exception { String className = listenerClass; if (attributeName != null) { String value = attributes.getValue(attributeName); if (value != null) className = value; } Class clazz = Class.forName(className); LifecycleListener listener = (LifecycleListener) clazz.newInstance(); Lifecycle lifecycle = (Lifecycle) digester.peek(); lifecycle.addLifecycleListener(listener); }
通过这个方法,将一个HostConfig对象加入到了StandardHost的LifecycleListener中去。而这里就是加载webapps的基础之处。
随后,随着Tomcat的启动,开始调用Bootstrap#start()。在start()方法中进而调用了一系列的start()。这其中就包括StandardHost#start()。
StandardHost#start()中的前面很多句都没有包含载入webapps的行为,直到最后一句,就是调用了super.start(),也就是调用了ContainerBase#start()。其中这样一句引发了载入webapps的行为:lifecycle.fireLifecycleEvent(START_EVENT, null);
也就是通知START_EVENT给所有的LifecycleListener,其中就包括了前面提到的HostConfig。HostConfig#lifecycleEvent()就是实现事件处理的方法,如下所示:
public void lifecycleEvent(LifecycleEvent event) { if (event.getType().equals(Lifecycle.PERIODIC_EVENT)) check(); try { host = (Host) event.getLifecycle(); if (host instanceof StandardHost) { setDeployXML(((StandardHost) host).isDeployXML()); setUnpackWARs(((StandardHost) host).isUnpackWARs()); setXmlNamespaceAware(((StandardHost) host).getXmlNamespaceAware()); setXmlValidation(((StandardHost) host).getXmlValidation()); } } catch (ClassCastException e) { log.error(sm.getString("hostConfig.cce", event.getLifecycle()), e); return; } // 这句判断了事件的类型,如果是START_EVENT方法就调用start() if (event.getType().equals(Lifecycle.START_EVENT)) start(); else if (event.getType().equals(Lifecycle.STOP_EVENT)) stop(); }
这个方法的最后判断了当出现START_EVENT时要调用start()方法。
public void start() { if (log.isDebugEnabled()) log.debug(sm.getString("hostConfig.start")); try { ObjectName hostON = new ObjectName(host.getObjectName()); oname = new ObjectName(hostON.getDomain() + ":type=Deployer,host=" + host.getName()); Registry.getRegistry(null, null).registerComponent(this, oname, this.getClass().getName()); } catch (Exception e) { log.error(sm.getString("hostConfig.jmx.register", oname), e); } if (host.getDeployOnStartup()) deployApps(); }
这个方法的最后调用了deployApps(),看名字就与部署应用程序有关系了,赶紧来看一下它写了什么。
protected void deployApps() { File appBase = appBase(); // 默认为webapps File configBase = configBase();// 默认为%TOMCAT_HOME%\conf\Catalina(Engine名)\localhost(Host名) // xml部署描述符 deployDescriptors(configBase, configBase.list()); // 部署war deployWARs(appBase, appBase.list()); // 部署文件夹形式的 deployDirectories(appBase, appBase.list()); }
这三个deploy*()方法分别负责载入三种形式的应用程序,这三个方法最后都会将应用程序的路径和对应的修改时间保存下来。方法太长就不详细介绍了。
发表评论
-
出现java.lang.UnsupportedClassVersionError 错误的原因
2010-08-16 23:11 871出现java.lang.UnsupportedClassVer ... -
Tomcat请求处理(七) - Servlet实例的调用
2009-05-07 11:36 1131Tomcat请求处理中Servlet实例的调用是和Filter ... -
请求在Tomcat中传到了CoyoteAdapter的#service()方法中后,就要准备进入Pi
2009-05-07 11:35 1811首先,来看一下Servlet的载入过程。 具体是在org.ap ... -
Tomcat请求处理(五) -- 请求在容器间的流动
2009-05-07 11:34 1433请求在Tomcat中传到了CoyoteAdapter的#ser ... -
Tomcat请求处理(四) -- Request, Response, 和Pipeline
2009-05-07 11:33 12841. Request和Response 当处理请求的时候,To ... -
Tomcat请求处理(三) -- coyote请求处理
2009-05-07 11:32 1325在上一篇文章文章中,Tomcat的请求处理到了JIoEndpo ... -
Tomcat请求处理(二) -- 请求处理框架
2009-05-07 11:30 991书接上文。 当Tomcat的Acceptor监听到有请求到来时 ... -
Tomcat请求处理(一) -- 服务器端口监听
2009-05-07 11:29 1402其实tomcat在哪个类中监听请求的代码很容易找到: 在org ... -
Tomcat启动部分源代码分析(四) -- 开启容器
2009-05-07 11:27 1205四. 开启容器 最后是Bootstrap#start()方法的 ... -
Tomcat启动部分源代码分析(三) -- 载入
2009-05-07 11:23 1195二. 载入 2. Bootstrap的#Bootstrap#l ... -
Tomcat启动部分源代码分析(二) -- 初始化
2009-05-07 11:20 1098二. 初始化 1. 首先是Bootstrap的#init()操 ... -
Tomcat启动部分源代码分析(一) -- 概览
2009-05-07 11:17 1433一. 概览 本文所涉及的Tomcat为6.0版本。 Tomca ... -
Tomcat的Session管理(二) - Session后台处理
2009-05-07 10:10 972Tomcat会开启一个后台线程每隔一段时间检查Session的 ... -
Tomcat的Session管理(一) - Session的生成
2009-05-07 10:02 1497Session对象的创建一般是源于这样的一条语句: Sessi ...
相关推荐
首先,Tomcat 7.0.42源代码是一个Maven项目,这意味着开发者可以利用支持Maven的集成开发环境(IDE)如IntelliJ IDEA或Eclipse,通过导入项目来直接进行阅读和分析。Maven是一个强大的项目管理和依赖管理工具,它...
Apache Tomcat 8的源代码目录结构清晰,主要分为以下几个部分: - `conf`:存放服务器配置文件,如`server.xml`和`web.xml`。 - `java`:包含核心组件的Java源代码,如Catalina、Jasper、Naming等。 - `webapps`...
通过分析这些组件的工作流程,你可以深入了解Tomcat如何加载Web应用程序,如何解析和执行JSP,以及如何管理连接池和线程池等。对于Java Web开发人员来说,理解Tomcat的源代码不仅有助于提升技术水平,还能为解决实际...
通过深入学习Apache Tomcat 8.5.68的源代码,开发者不仅可以理解Web服务器的工作原理,还可以掌握如何定制Tomcat以满足特定需求,进一步提升应用程序的性能和稳定性。同时,这也是Java Web开发人员进阶的重要一步。
1. **Catalina**:这是Tomcat的核心组件,负责管理Web应用程序,包括加载、部署、启动和停止应用。`org.apache.catalina`包下包含了大部分核心类,如`Engine`(顶层容器)、`Host`(虚拟主机)、`Context`(Web应用...
Tomcat6的源代码结构清晰,主要包含以下几个关键部分: - common:公共库,包含所有Tomcat实例共享的组件。 - conf:配置文件目录,包括server.xml等核心配置文件。 - server:服务器特定的库,如Catalina核心组件。...
Apache Tomcat是一款开源的Java Servlet容器,主要用于部署和运行Java Web应用程序。它的核心功能是解析并执行基于Java Servlet和JavaServer Pages(JSP)技术的Web应用。在本压缩包"apache-tomcat-6.0.29.zip"中,...
Apache Tomcat 6.0.41是一款广泛应用的开源Java Servlet容器,主要用于部署和运行Java Web应用程序。这个源代码版本提供了深入理解Tomcat工作原理的机会,对于开发者来说是一份宝贵的资源。下面将详细介绍Tomcat ...
【JBoss5源代码分析-官方-第二部分】 JBoss5是JBoss企业应用平台(JBoss Enterprise Application Platform)的一个重要版本,它基于Java EE 5规范,为开发者提供了全面的中间件服务,包括Web服务器、EJB容器、JMS...
Apache Tomcat是一款开源的Java Servlet容器,用于部署和运行Java Web应用程序。它的源代码是公开的,这使得开发者能够深入理解其内部工作原理,优化性能,或者为它添加自定义功能。以下是对Tomcat源码及其分析的...
当你下载并解压Tomcat 8的源代码后,可以将其导入Eclipse或其他IDE中进行分析和学习。源代码目录结构清晰,包括`common`, `conf`, `webapps`, `work`, `logs`, `bin`, 和 `lib`等目录,它们各自承载着特定的功能。 ...
《深入剖析Tomcat 6.0源代码》 Tomcat,作为Apache软件基金会的一个开源项目,是Java Servlet和JavaServer Pages(JSP)容器的首选,尤其在轻量级应用服务器领域,它以其高效、稳定和易用性而受到广泛的赞誉。...
【标题】"Tomcat 8源代码 Servlet源代码" 涉及到的是Apache Tomcat服务器的源码分析,特别是Servlet容器的相关实现。Tomcat是一个开源的轻量级Web应用服务器,广泛用于部署Java Servlet和JavaServer Pages (JSP)应用...
主要的目录包括`bin`(用于启动和管理Tomcat的脚本)、`conf`(配置文件)、`lib`(包含运行时所需的JAR文件)、`webapps`(默认的应用程序存放位置)以及`src`(源代码目录)。在`src`目录下,有`java`和`native`子...
Apache Tomcat 7.0.94 是一个广泛使用的开源软件,它是一个实现了Java Servlet、JavaServer Pages(JSP)和Java EE的Web应用程序容器。这个版本是Tomcat 7系列的一个更新,提供了稳定性和安全性的改进。由于解压后...
3. **Tomcat启动流程**: - 加载配置文件,如server.xml,定义了服务器的各个组件(例如Catalina、Connector、Engine、Host、Context等)。 - 初始化生命周期监听器,执行它们的初始化方法。 - 创建并启动必要的...
- **Jasper**:这是一个JSP编译器,将JSP页面转换为Servlet源代码并编译成.class文件。 - **Connector**:处理HTTP请求和响应,是Tomcat与Web客户端通信的桥梁。 - ** Coyote**:Tomcat的HTTP/1.1连接器,负责...
Tomcat 5.0.28是其历史上的一个重要版本,以其稳定性而著称,对于理解和优化Java Web应用程序的运行机制具有极高的学习价值。 首先,我们要理解Tomcat的基本架构。Tomcat主要由以下几个核心组件构成: 1. **...
- **System类加载器**:加载Tomcat启动所需的类,如bootstrap.jar。 - **Common类加载器**:加载Tomcat共用的类库,这些类库位于`CATALINA_HOME/lib`目录下。 - **Webapp类加载器**:每个Web应用程序都有自己独立...
理解并熟练使用Jakarta Tomcat Connectors JK对于优化大型Web应用程序的性能和可扩展性至关重要。通过源码学习,开发者可以深入理解其内部机制,解决可能遇到的问题,或者根据特定需求定制功能。