学习tomcat 小记(7)
StandardContext类
创建了StandardContext实例后,必须调用调用其start方法来准备接收http请求。但是,在调用start方法时,可能会报错,这时StandardContext对象的available属性会被置为false,available属性表明了StandardContext对象是否可用。
若要是start方法正确执行,必须正确对StandardContext对象正确配置。tomcat中,配置StandardContext对象需要一系列操作。正确设置后,StandardContext对象才能读取并解析web.xml文件。
1)StandardContext的配置
StandardContext类的构造函数
构造函数中最重要的事情是为pipeline设置basic valve,org.apache.catalina.core.StandardContextValve。该valve会处理从connector中接收到的http请求。
启动StandardContext
start方法初始化StandardContext对象,用监听器配置StandardContext实例。
下面是start方法要做的一些事:
(1)触发BEFORE_START事件;
(2)将availability和configured属性设置为false;
(3)设置resources,loader,manager;
(4)初始化字符串映射;
(5)启动与该context关联的组件;
(6)启动子container;
(7)启动pipeline;
(8)启动manager;
(9)触发START事件,这里监听器(ContextConfig)会执行一些配置操作,若设置成功,ContextConfig会将StandardContext实例的configured变量设置为true;
(10)检查configured属性的值,若为true,调用postWelcomePages方法,载入子wrapper,将availability属性设置为true。若configured为false,则调用stop方法;
(11)触发AFTER_START事件。
invoke方法
在tomcat4中,StandardContext的invoke方法由相关联的connector调用,或者当StandardContext是一个子container时,由host的invoke方法调用。StandardContext的invoke方法第一次调用时会检查应用程序是否正在重载过程中,若是,则等待应用程序重载完成。然后,调用其父类(ContainerBase)的invoke方法。
在tomcat5中,StandardContext类并没有提供invoke方法的实现,因此会调用ContainerBase的invoke方法,检查应用程序是否在重载的工作被移到了StandardContextValve类的invoke方法中。
StandardContextMapper类
对于每个接收到的http请求,都会调用StandardContext的pipeline的basic valve。StandardContext的basic valve是org.apache.catalina.core.StandardContextValve类实现的。StandardContextValve.invoke方法要做的第一件事是获取一个wrapper对象处理请求。
在tomcat4中,StandardContextValve实例使用context的mapper找到一个合适的wrapper使用。一一旦获得了wrapper,就会调用wrapper的invoke方法。
在tomcat5中,删除Mapper接口及其相关类,而是从request对象的getWrapper方法中获取wrapper对象。
对重载的支持
StandardContext类中定义了reloadable属性来指明该应用是否启用的重载功能。当启用了重载后,当web.xml或WEB-INF/classes目录下文件被重新编译后,应用程序会重载。
StandardContext类是通过其loader实现应用程序重载的。在tomcat4中,StandardContext对象中的WebappLoader类实现了Loader接口,并使用另一个线程检查WEB-INF目录中的类和jar的时间戳。只需要调用setContainer方法将WebappLoader对象与StandardContext对象相关联就可以启动该检查线程。
backgroundProcess方法
context的运行需要其他组件的支持,例如loader和manager。通常来说,这些组件需要使用各自的线程执行一些后台处理任务。例如,为了支持自动重载,loader组件需要使用一个线程周期性的检查类和jar的时间戳;manager组件使用一个线程检查它所管理的session对象的过期时间。在tomat4中,这些组件都开启了各自的线程完成工作。
在tomcat5中,使用了不同的方法。所有的后台处理共享同一的线程。若某个组件或container需要周期性的执行一个操作,只需要将代码写到backgroundProcess方法中即可。
这个共享线程由ContainerBase对象创建,并在其start方法中调用threadStart方法
下一小结将是Host和Engine