How Tomcat works之StandardContext 标准上下文
来源:互联网 发布:生化危机人工智能红后 编辑:程序博客网 时间:2024/06/11 21:16
回顾
就如在前面章节所看的,一个上下文代表一个web应用并包含了一个或者更多的wrapper,每个代表一个servlet定义。然而,一个上下文也需要其他的组件,尤其是加载器和管理器。这章演示了StandardContext类,基于接口Context实现。
首先我们将先看StandardContext对象的实例化和配置。之后讨论与其相关的类StandardContextMapper(在Tomcat 4中)和ContextConfig。下一步,我们查看每个来的HTTP请求的方法执行顺序。之后,再讨论StandardContext的重要属性。最后,讨论了Tomcat 5中的backgroundProcess方法。
StandardContextConfiguration
在一个StandardContext实例被构建后,它的start方法必须被调用使实例可以服务到来的HTTP请求。由于这样那样的原因,StandardContext对象可能启动失败。如果这种情况发生了,StandardContext对象的有效属性将被设置为false。course的有效属性标示了StandardContext的有效性。
启动成功,StandardContext对象必须被有效配置。在一个Tomcat 部署中,StandardContext的配置做大量的事情。这样context能够读和解析web.xml文件,位于%CATALINA_HOME%conf目录下并应用于所有的额应用部署。它也保证StandardContext实例能处理应用级别的web.xml文件。另外,configuration安装了一个校验值和证书值。
注意更多的StandardContext的configuration在第十五章中讨论
StandardContext类的属性中的一个是configurated属性,是一个boolean值用来指明StandardContext实例是否被合理配置。StandardContext使用好似一个时间监听器作为其配置器。当StandardContext实例的start方法被调用,其中一件事情是触发一个生命周期时间。这个事件调用监听器反过来将配置StandardContext实例。如果配置成功,监听器将设置configurated属性为true。否则,StandardContext将拒绝启动并不能服务HTTP请求。
在第十一章中,你看见一个生命周期接口的实现,添加到StandardContext实例中。它的类型是ch11.pyrmont.core.SimpleContextConfig并且仅仅简单地设置了StandardContext的configurated属性为true,而不用任何其他事情,仅仅就是欺骗StandardContext认为已经被合理配置。在一个Tomcat部署中,生命周期接口(用来配置StandardContext的)是一个ContextConfig类型,将在第十五章中讨论。
注意你理解了StandardContext配置的重要性。现在看看StandardContext的细节,从构造器的启动开始。
StandardContextClass的构造器
这里是StandardContext的构造器
publicStandardContext() { super(); pipeline.setBasic(new StandardContextValve());namingResources.setContainer(this); }
在上面构造器中需要注意的最重要的事情是StandardContext的pipeline,其被传入了一个StandardContextVlaue类型的的基本值。这个值将处理每个来自连接器的HTTP请求。
StartingStandardContext
Start方法初始化了StandardContext实例并使生命周期接口有机会配置StandardContext实例。这个监听器在配置StandardContext成功后设置configurated属性为true。结束时,start方法设置available属性为true或者false。True值意味着StandardContext实例已经被合理配置并且所有的子容器和组件已经成功启动。因此StandardContext实例已经准备服务即将到来的HTTP请求。False则表明相反。
StandardContext类安排一个叫做configurated的boolean值,初始化为false。如果生命周期接口成功完成了StandardContext的配置任务,configurated属性值将设置为true。在start方法的最后,StandardContext检查这个属性值。如果为true,这个StandardContext已经成功启动。否则,调用stop方法停止已经被start方法启动的组件。
在Tomcat 4中的start方法定义如下:
publicsynchronized void start() throws LifecycleException { if (started) throw newLifecycleException (sm.getString("containerBase.alreadyStarted",logName())); if (debug >= 1) log("Starting");
// Notify ourinterested LifecycleListeners lifecycle.fireLifecycleEvent(BEFORE_START_EVENT,null); if (debug >= 1) log("Processing start(), currentavailable=" + getAvailable()); setAvailable(false); setConfigured(false);boolean ok = true; // Add missing components as necessary if (getResources() ==null) { // (1) Required by Loader
if (debug >= 1)log("Configuring default Resources"); try { if ((docBase != null)&& (docBase.endsWith(".war"))) setResources(newWARDirContext()); else setResources(new FileDirContext()); } catch(IllegalArgumentException e) { log("Error initializing resources: " +e.getMessage()); ok = false; } }
if (ok &&(resources instanceof ProxyDirContext)) { DirContext dirContext =((ProxyDirContext) resources).getDirContext(); if ((dirContext != null)&& (dirContext instanceof BaseDirContext)) { ((BaseDirContext) dirContext).setDocBase(getBasePath());((BaseDirContext) dirContext).allocate(); } }
if (getLoader() ==null) { // (2) Required by Manager if (getPrivileged()) { if (debug >= 1)log("Configuring privileged default Loader"); setLoader(newWebappLoader(this.getClass().getClassLoader())); } else { if (debug >= 1)log("Configuring non-privileged default Loader"); setLoader(newWebappLoader(getParentClassLoader())); } }
if (getManager()== null) { // (3) After prerequisites if (debug >= 1) log("Configuringdefault Manager"); setManager(new StandardManager()); }
// Initializecharacter set mapper
getCharsetMapper();
// Post workdirectory
postWorkDirectory();
// Reading the"catalina.useNaming" environment variable
StringuseNamingProperty = System.getProperty("catalina.useNaming"); if((useNamingProperty != null) &&(useNamingProperty.equals("false"))) { useNaming = false; }
if (ok &&isUseNaming()) { if (namingContextListener == null) { namingContextListener =new NamingContextListener(); namingContextListener.setDebug(getDebug());
namingContextListener.setName(getNamingContextName());addLifecycleListener(namingContextListener); } }
// Binding thread
ClassLoader oldCCL= bindThread();
// Standardcontainer startup
if (debug >= 1)log("Processing standard container startup");
if (ok) {
try {
addDefaultMapper(this.mapperClass);
started = true;
// Start our subordinate components, if any
if ((loader != null) && (loader instanceofLifecycle))
((Lifecycle) loader).start();
// Unbinding thread
unbindThread(oldCCL);
// Binding thread
oldCCL = bindThread();
if ((cluster != null) && (cluster instanceofLifecycle)) ((Lifecycle) cluster).start(); if ((realm != null) &&(realm instanceof Lifecycle)) ((Lifecycle) realm).start(); if ((resources !=null) && (resources instanceof Lifecycle)) ((Lifecycle)resources).start();
// Start our Mappers, if any
Mapper mappers[] = findMappers(); for (int i = 0; i< mappers.length; i++) { if (mappers[i] instanceof Lifecycle) ((Lifecycle)mappers[i]).start(); }
// Start our child containers, if any
Container children[] = findChildren(); for (int i = 0;i < children.length; i++) { if (children[i] instanceof Lifecycle)((Lifecycle) children[i]).start(); }
// Start the Valves in our pipeline (including thebasic),
// if any
if (pipeline instanceof Lifecycle) ((Lifecycle) pipeline).start();
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(START_EVENT, null);
if ((manager != null) && (manager instanceofLifecycle)) ((Lifecycle) manager).start();
}
finally { // Unbinding thread unbindThread(oldCCL); }}
if (!getConfigured()) ok = false;
// We put the resources into the servlet context
if (ok) getServletContext().setAttribute(Globals.RESOURCES_ATTR, getResources());
// Binding thread
oldCCL = bindThread();
// Create context attributes that will be required
if (ok) { if (debug >= 1) log("Postingstandard context attributes"); postWelcomeFiles(); }
// Configure and call application event listeners andfilters
if (ok) { if (!listenerStart())
ok = false; }
if (ok) { if (!filterStart()) ok = false; }
// Load and initialize all "load on startup"servlets
if (ok) loadOnStartup(findChildren());
// Unbinding thread
unbindThread(oldCCL);
// Set available status depending upon startup success
if (ok) { if (debug >= 1) log("Startingcompleted"); setAvailable(true); } else {log(sm.getString("standardContext.startFailed")); try { stop(); }catch (Throwable t) {log(sm.getString("standardContext.startCleanup"), t); } setAvailable(false);}
// Notify ourinterested LifecycleListenerslifecycle.fireLifecycleEvent(AFTER_START_EVENT, null); }
注意 在Tomcat 5中的start方法与Tomcat 4的start方法相似。然而,其包含了JMX相关的代码。JMX将在第20章中讲解。
Start方法将完成一系列事情
1 触发BEFORE_START时间
2 设置availability属性为false
3 设置configurated属性为false
4 设置资源
5 设置加载器
6 设置管理器
7 初始化字符设置映射
8 启动与context相关的其他组件
9 启动子容器(比如wrapper)
10 启动管道
11 启动管理器
12 触发START事件。这里监听器(ContextConfig)将处理一些配置操作(在第十五章中讨论)。在成功配置后,ContextConfig将设置StandardContext的configurated属性为true
13 检查configurated属性值。如果是true,做一下事情:调用postWelcomepages方法,加载子wrappres,需要在start-up的时候加载,并设置availabilty属性为true。如果configurated为false,调用stop方法。
14 触发AFLTER_START事件
- How Tomcat works之StandardContext 标准上下文
- How tomcat works 读书笔记十二 StandardContext 上
- How tomcat works 读书笔记十二 StandardContext 下
- How tomcat works——12 StandardContext
- How Tomcat works 之 StandardWrapper 标准包装
- How Tomcat works 之The Application 应用
- How Tomcat works之 Host and Engine
- How Tomcat Works之ex01时序图
- How Tomcat Works 1
- How Tomcat Works 2
- Books - How Tomcat works
- How Tomcat Works 5
- How Tomcat Works 9
- How Tomcat Works 6
- How Tomcat Works 8
- How Tomcat Works 11
- How Tomcat Works 12
- How Tomcat Works 13
- byte,short,char类型的运算
- AT&T与Intel格式的汇编语法
- How Tomcat works之第十一章之ApplicationFilterChain
- △【OJ】---Q---比较大小-类模板
- OCP 1Z0 052 V9.02 201
- How Tomcat works之StandardContext 标准上下文
- MySQL与一些简单查询命令
- Array of Strings to Convert to Mixed Array
- 基于Atmel128A单片机的工业以太网卡设计(实现uip1.0协议)
- How Tomcat Works之第十二章之invoke方法
- web.xml之load-on-startup
- 【OJ】---R---复数类--重载运算符+
- validation插件忽略校验
- 人生领悟