《How tomcat works》读书笔记_加载器_Application

应用程序

下面将讨论如何使用一个与Context关联的WebappLoader。Context容器的标准实现是org.apache.catalina.core.StandardContext,程序中将使用StandardContext类作为Context容器。StandardContext类将在后面章节讨论,现在不需要知道太多关于这个类的细节。你只需要知道StandardContext与一个监听器协同,监听它派发的START_EVENT和STOP_EVENT事件。监听器必须实现org.apache.catalina.lifecycle.LifecycleListener接口并且调用StandardContext类的setConfigured方法。在这个应用中,监听器为ex08.pyrmont.core.SimpleContextConfig类,代码如下:

package ex08.pyrmont.core;

import org.apache.catalina.Context;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleListener;

public class SimpleContextConfig implements LifecycleListener {

    public void lifecycleEvent(LifecycleEvent event) {
        if (Lifecycle.START_EVENT.equals(event.getType())) {
            Context context = (Context) event.getLifecycle();
            context.setConfigured(true);
        }
    }
}

你需要作的就是实例化StandardContext和SimpleContextConfig类,然后调用org.apache.catalina.Lifecycle接口的addLifecycleListener方法将SimpleContextConfig注册到StandardContext中。Lifecycle接口已经在前面章节详细介绍过了。

程序可以使用PrimitiveServlet和ModernServlet这两个servlet来测试,但是和前面章节不同的是,StandardContext类要求servlet的class类要保存在应用的WEB-INF/classes目录下。本章应用的目录为myApp。设置一个名为“catalina.base”的系统属性来告诉StandardContext在哪儿查找应用目录,这个属性的值同属性user.dir的值。如下:

System.setProperty("catalina.base",System.getProperty("user.dir"));

这是Bootstrap类main方法执行的第一行代码,然后main方法会实例化一个默认连接器

Connector connector = new HttpConnector();

然后为两个servlet初始化两个Wrapper容器

Wrapper wrapper1 = new SimpleWrapper();
wrapper1.setName("Primitive");
wrapper1.setServletClass("PrimitiveServlet");
Wrapper wrapper2 = new SimpleWrapper();
wrapper2.setName("Modern");
wrapper2.setServletClass("ModernServlet");

接下来,创建一个StandardContext实例,并设置Context的path和document base。

Context context = new StandardContext();
// StandardContext's start method adds a default mapper
context.setPath("/myApp");
context.setDocBase("myApp");

以上操作相当于在Tomcat的server.xml文件中增加以下配置

<Context path="/myApp" docBase="myApp"/>

接下来,将Wrapper容器添加到Context容器中并注册映射信息,这样Context就可以在不同请求的情况下调用不同的Wrapper。

context.addChild(wrapper1);
context.addChild(wrapper2);
// context.addServletMapping(pattern, name);
context.addServletMapping("/Primitive", "Primitive");
context.addServletMapping("/Modern", "Modern");

下一步是初始化一个监听器,并在Context容器中注册这个监听器

LifecycleListener listener = new SimpleContextConfig();
((Lifecycle) context).addLifecycleListener(listener);

然后实例化WebappLoader,将它与Context容器关联

// here is our loader
Loader loader = new WebappLoader();
// associate the loader with the Context
context.setLoader(loader);

完成以上工作之后,将Context容器与默认连接器关联,调用连接器的initialize和start方法,这样servlet容器就可以工作了。

connector.setContainer(context);
try {
    connector.initialize();
    ((Lifecycle) connector).start();
    ((Lifecycle) context).start();

接下来的代码中只是在控制台打印资源的docBase和加载器中所有的库。

// now we want to know some details about WebappLoader
WebappClassLoader classLoader = (WebappClassLoader) loader.getClassLoader();
System.out.println("Resources' docBase: "+ ((ProxyDirContext)classLoader.getResources()).getDocBase());
String[] repositories = classLoader.findRepositories();
for (int i = 0; i < repositories.length; i++) {
    System.out.println("  repository: " + repositories[i]);
}

最后,程序会一直运行直到在控制台输入回车符停止。

// make the application wait until we press a key.
System.in.read();
((Lifecycle) context).stop();

运行程序

启动程序控制台输出

HttpConnector Opening server socket on all host IP addresses
HttpConnector[8080] Starting background thread
WebappLoader[/myApp]: Deploying class repositories to work directory C:\Users\Administrator\git\HowTomcatWorks\work\_\_\myApp
WebappLoader[/myApp]: Deploy class files /WEB-INF/classes to C:\Users\Administrator\git\HowTomcatWorks\myApp\WEB-INF\classes
Starting Wrapper Primitive
Starting Wrapper Modern
StandardManager[/myApp]: Seeding random number generator class java.security.SecureRandom
StandardManager[/myApp]: Seeding of random number generator has been completed
Resources' docBase: C:\Users\Administrator\git\HowTomcatWorks\myApp
  repository: /WEB-INF/classes/

关闭程序时控制台输出

Stopping wrapper Primitive
Stopping wrapper Modern

总结

Web应用加载器,或是一个简单的加载器,是Catalina中最重要的组件。一个加载器使用其内部的类加载器来加载类文件。在Tomcat中,这个内部的类加载器是一个定制的加载器,在一个Web应用中它执行相应的规则来加载一个类。同时,这个定制的类加载器支持缓存以及是否类文件被修改过。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值