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

相关推荐

    JAVA上百实例源码以及开源项目源代码

    Java 3DMenu 界面源码 5个目标文件 内容索引:Java源码,窗体界面,3DMenu Java 3DMenu 界面源码,有人说用到游戏中不错,其实平时我信编写Java应用程序时候也能用到吧,不一定非要局限于游戏吧,RES、SRC资源都有,都...

    JSP动态网页制作基础培训教程源代码.rar

    此部分是指文件夹名为第1~9章中的内容(如表1),这些是书中介绍JSP相关知识的源代码。文件的命名规则与书中相应源代码文件名一致。读者可将相关文件夹(如ch2)拷贝到Tomcat服务器安装目录的子目录webapps下,并...

    java源码部署-Spoing:库和示例可简化从一个Java源代码库构建和部署跨平台(Windows,Linux,MacOS和Web)应用程序

    Spoing是一组库和示例源代码,可简化从一个纯Java源代码库构建和部署轻量级,快速加载,跨平台(Windows,Linux和MacOS)的桌面和Web应用程序的过程。 不需要XML,CSS,HTML,Javascript或完全不同的Web /桌面Java源...

    Java类加密程序

    例如,本加密工具安装在c:\hideasoft\java_protect,执行加密后的CLASS文件的命令行如下: java -agentlib:c:\hideasoft\java_protect\hidea &lt;您的CLASS类及参数&gt; 应用场合 独立的应用程序(Application,...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part2

    5.5.3 tomcat启动分析 189 5.5.4 tomcat的体系结构 191 5.6 tomcat的管理程序 193 5.6.1 admin web应用程序 193 5.6.2 manager web应用程序 194 5.7 小结 195 第6章 servlet技术 196 6.1 servlet api 196 ...

    基于ssh和mysql的教材交易系统

    1、安装Java: 安装的是jdk1.7.0_09,安装... war包在tomcat启动时会自动解压并加载应用。 5、启动tomcat服务器,这样就可以通过本地浏览器访问http://localhost/8080/dangdang/main/mian.jsp 进入系统应用主页了。

    Java类加密2.0版本,无限制

    独立的应用程序(Application,自定义main方法),运行java时,带上参数-agentlib:&lt;所在路径&gt;\lanswon Tomcat等JAVA Web Server,修改启动脚本,把执行java的命令行加上参数-agentlib:&lt;所在路径&gt;\lanswon JBOSS等...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part3

    5.5.3 tomcat启动分析 189 5.5.4 tomcat的体系结构 191 5.6 tomcat的管理程序 193 5.6.1 admin web应用程序 193 5.6.2 manager web应用程序 194 5.7 小结 195 第6章 servlet技术 196 6.1 servlet api 196 ...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part4

    5.5.3 tomcat启动分析 189 5.5.4 tomcat的体系结构 191 5.6 tomcat的管理程序 193 5.6.1 admin web应用程序 193 5.6.2 manager web应用程序 194 5.7 小结 195 第6章 servlet技术 196 6.1 servlet api 196 ...

    单点登录源码

    - 统一下单(统一下单接口、统一扫码)、订单管理、数据分析、财务报表、商户管理、渠道管理、对账系统、系统监控。 ![统一扫码支付](project-bootstrap/zheng-pay.png) &gt; zheng-ucenter 通用用户管理系统, 实现...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part5

    5.5.3 tomcat启动分析 189 5.5.4 tomcat的体系结构 191 5.6 tomcat的管理程序 193 5.6.1 admin web应用程序 193 5.6.2 manager web应用程序 194 5.7 小结 195 第6章 servlet技术 196 6.1 servlet api 196 ...

    JAVA上百实例源码以及开源项目

     Java 3DMenu 界面源码,有人说用到游戏中不错,其实平时我信编写Java应用程序时候也能用到吧,不一定非要局限于游戏吧,RES、SRC资源都有,都在压缩包内。 Java zip压缩包查看程序源码 1个目标文件 摘要:Java源码...

    高级java笔试题-itresource:程序开发技术资源集合

    heavyz的Tomcat学习笔记(包括启动流程分析、启动脚本分析) ] () [ java8 新特性讲解系列文章 ] () [ Java 从Jar文件中动态加载类 ] () [ Java并发源码分析 - ThreadPoolExecutor ] () [ java ClassLoader 基本原理 ]...

    springboot参考指南

    改变应用程序外部配置文件的位置 iii. 63.3. 使用'short'命令行参数 iv. 63.4. 使用YAML配置外部属性 v. 63.5. 设置生效的Spring profiles vi. 63.6. 根据环境改变配置 vii. 63.7. 发现外部属性的内置选项 iii. 64....

    java class加密保护工具

    很容易被反编译工具反编译,而传统的java源代码保护方法基本都是采用混淆的方式, 但这样会带来很多麻烦,而且也不能真正保护class文件, 本工具是对class文件进行加密,采用jni的方式解密运行, 加密算法达到256位...

    《MyEclipse 6 Java 开发中文教程》前10章

    第二章 开发第一个Java应用程序 46 2.1 介绍 46 2.2 手工编写,编译并运行Java程序 46 2.3 使用Eclipse/MyEclipse来编写,编译并运行Java程序 47 2.4小结 50 第三章 Eclipse 的基础概念,配置和使用 51 3.1界面布局 ...

    java class加密保护(完全免费) v2.1

    很容易被反编译工具反编译,而传统的java源代码保护方法基本都是采用混淆的方式, 但这样会带来很多麻烦,而且也不能真正保护class文件, 本工具是对class文件进行加密,采用jni的方式解密运行, 加密算法达到256位...

    我心飞扬java类加密工具2.1(亲测可用)

    众所周知,java编译后的class文件是一种中间字节字文件,很容易被反编译工具反编译,而传统的java源代码保护方法基本都是采用混淆的方式,但这样会带来很多麻烦,而且也不能真正保护class文件,本工具是对class文件...

    Java类加密工具v2.2(免注册)

    很容易被反编译工具反编译,而传统的java源代码保护方法基本都是采用混淆的方式, 但这样会带来很多麻烦,而且也不能真正保护class文件, 本工具是对class文件进行加密,采用jni的方式解密运行, 加密算法达到256...

Global site tag (gtag.js) - Google Analytics