`
刘琛颖
  • 浏览: 49977 次
  • 性别: Icon_minigender_1
  • 来自: 成都
最近访客 更多访客>>
社区版块
存档分类
最新评论

Tomcat启动部分源代码分析(五) -- 应用程序加载

阅读更多
前面所叙述的tomcat启动中并没有webapps下边应用程序载入的内容,今天花了些时间在源代码中找到了一些相关的内容。

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*()方法分别负责载入三种形式的应用程序,这三个方法最后都会将应用程序的路径和对应的修改时间保存下来。方法太长就不详细介绍了。
分享到:
评论

相关推荐

    Tomcat:tomcat源代码maven项目-tomcat source code

    首先,Tomcat 7.0.42源代码是一个Maven项目,这意味着开发者可以利用支持Maven的集成开发环境(IDE)如IntelliJ IDEA或Eclipse,通过导入项目来直接进行阅读和分析。Maven是一个强大的项目管理和依赖管理工具,它...

    Tomcat8源代码

    Apache Tomcat 8的源代码目录结构清晰,主要分为以下几个部分: - `conf`:存放服务器配置文件,如`server.xml`和`web.xml`。 - `java`:包含核心组件的Java源代码,如Catalina、Jasper、Naming等。 - `webapps`...

    apache-tomcat-7 源代码

    通过分析这些组件的工作流程,你可以深入了解Tomcat如何加载Web应用程序,如何解析和执行JSP,以及如何管理连接池和线程池等。对于Java Web开发人员来说,理解Tomcat的源代码不仅有助于提升技术水平,还能为解决实际...

    Tomcat6源代码学习(运行源代码及调试)

    Tomcat6的源代码结构清晰,主要包含以下几个关键部分: - common:公共库,包含所有Tomcat实例共享的组件。 - conf:配置文件目录,包括server.xml等核心配置文件。 - server:服务器特定的库,如Catalina核心组件。...

    apache-tomcat-6.0.29.zip

    Apache Tomcat是一款开源的Java Servlet容器,主要用于部署和运行Java Web应用程序。它的核心功能是解析并执行基于Java Servlet和JavaServer Pages(JSP)技术的Web应用。在本压缩包"apache-tomcat-6.0.29.zip"中,...

    Tomcat6.0.41源代码,可直接导入Eclipse

    Apache Tomcat 6.0.41是一款广泛应用的开源Java Servlet容器,主要用于部署和运行Java Web应用程序。这个源代码版本提供了深入理解Tomcat工作原理的机会,对于开发者来说是一份宝贵的资源。下面将详细介绍Tomcat ...

    Jboss5源代码-官方-第二部分

    【JBoss5源代码分析-官方-第二部分】 JBoss5是JBoss企业应用平台(JBoss Enterprise Application Platform)的一个重要版本,它基于Java EE 5规范,为开发者提供了全面的中间件服务,包括Web服务器、EJB容器、JMS...

    TOMCAT源代码,包括转载得别人的分析

    Apache Tomcat是一款开源的Java Servlet容器,用于部署和运行Java Web应用程序。它的源代码是公开的,这使得开发者能够深入理解其内部工作原理,优化性能,或者为它添加自定义功能。以下是对Tomcat源码及其分析的...

    tomcat8源代码

    当你下载并解压Tomcat 8的源代码后,可以将其导入Eclipse或其他IDE中进行分析和学习。源代码目录结构清晰,包括`common`, `conf`, `webapps`, `work`, `logs`, `bin`, 和 `lib`等目录,它们各自承载着特定的功能。 ...

    tomcat6.0的源代码

    《深入剖析Tomcat 6.0源代码》 Tomcat,作为Apache软件基金会的一个开源项目,是Java Servlet和JavaServer Pages(JSP)容器的首选,尤其在轻量级应用服务器领域,它以其高效、稳定和易用性而受到广泛的赞誉。...

    Tomcat 8源代码 Servlet源代码

    【标题】"Tomcat 8源代码 Servlet源代码" 涉及到的是Apache Tomcat服务器的源码分析,特别是Servlet容器的相关实现。Tomcat是一个开源的轻量级Web应用服务器,广泛用于部署Java Servlet和JavaServer Pages (JSP)应用...

    apache-tomcat-8.0.9-src源代码

    主要的目录包括`bin`(用于启动和管理Tomcat的脚本)、`conf`(配置文件)、`lib`(包含运行时所需的JAR文件)、`webapps`(默认的应用程序存放位置)以及`src`(源代码目录)。在`src`目录下,有`java`和`native`子...

    Tomcat源码apache-tomcat-8.5.47-src.zip

    1. **Catalina**:这是Tomcat的核心组件,负责管理Web应用程序,包括加载、部署、启动和停止应用。`org.apache.catalina`包下包含了大部分核心类,如`Engine`(顶层容器)、`Host`(虚拟主机)、`Context`(Web应用...

    apache-tomcat-7.0.57-src

    3. **Tomcat启动流程**: - 加载配置文件,如server.xml,定义了服务器的各个组件(例如Catalina、Connector、Engine、Host、Context等)。 - 初始化生命周期监听器,执行它们的初始化方法。 - 创建并启动必要的...

    apache-tomcat-8.5.47-windows-x64.zip

    - **Jasper**:这是一个JSP编译器,将JSP页面转换为Servlet源代码并编译成.class文件。 - **Connector**:处理HTTP请求和响应,是Tomcat与Web客户端通信的桥梁。 - ** Coyote**:Tomcat的HTTP/1.1连接器,负责...

    Tomcat5.0.28源代码

    Tomcat 5.0.28是其历史上的一个重要版本,以其稳定性而著称,对于理解和优化Java Web应用程序的运行机制具有极高的学习价值。 首先,我们要理解Tomcat的基本架构。Tomcat主要由以下几个核心组件构成: 1. **...

    Java 类在 Tomcat 中是如何加载的(过程分析)

    - **System类加载器**:加载Tomcat启动所需的类,如bootstrap.jar。 - **Common类加载器**:加载Tomcat共用的类库,这些类库位于`CATALINA_HOME/lib`目录下。 - **Webapp类加载器**:每个Web应用程序都有自己独立...

    apache-tomcat-8.5.68-src

    通过深入学习Apache Tomcat 8.5.68的源代码,开发者不仅可以理解Web服务器的工作原理,还可以掌握如何定制Tomcat以满足特定需求,进一步提升应用程序的性能和稳定性。同时,这也是Java Web开发人员进阶的重要一步。

    jakarta-tomcat-connectors-jk-1.2.6-src.zip

    理解并熟练使用Jakarta Tomcat Connectors JK对于优化大型Web应用程序的性能和可扩展性至关重要。通过源码学习,开发者可以深入理解其内部机制,解决可能遇到的问题,或者根据特定需求定制功能。

    tomcat5.5源代码

    Tomcat以其轻量级、高效和可扩展性而闻名,它是许多Web应用程序开发者的首选服务器。在深入研究Tomcat 5.5的源代码时,我们可以学习到以下几个关键知识点: 1. **Servlet和JSP规范**: Tomcat 5.5遵循Servlet 2.4...

Global site tag (gtag.js) - Google Analytics