- 浏览: 68566 次
- 性别:
- 来自: 成都
最新评论
-
qiaohhgz:
public static void String chang ...
一图和几句话解决java参数传值问题 -
ocaicai:
虽然我看懂了你的意思,但是我依然觉得表达得有些欠妥!
一图和几句话解决java参数传值问题 -
ql0722:
特别赞同第二条第三条
如果我再年轻几岁 -
zzc_zj:
很好的知识点,学习了
数据库查询select原理 -
dai03070609:
[url][/url][flash=200,200][/fla ...
数据库查询select原理
Chapter 6: Lifecycle
Catalina是由许多组件组成的。当Catalina启动时,这些组件也需要跟着启动。当Catalina停止,这些组件也必须得到被清理的机会。例如,当一个容器停止,它必须调用加载了的所有的servlet的destroy方法,session管理器必须把session对象保存到辅助存储器。一个统一的用来启动和停止组件的机制是通过实现org.apache.catalina.Lifecycle接口。
一个实现了Lifecycle接口的组件可以触发一个或许多事件:BEFORE_START_EVENT, START_EVENT, AFTER_START_EVENT, BEFORE_STOP_EVENT, STOP_EVENT和AFTER_STOP_EVENT。当通常一个启动组件时触发前三个事件,当停止组件时触发三个事件。一个事件由org.apache.catalina.LifecycleEvent类代表。最后,当然,如果一个Catalina组件想要能够触发事件,这里必须有事件监听器。事件监听器让你来处理这些事件的响应。一个监听器由org.apache.catalina.LifecycleListener接口代表。
这章将讨论Lifecycle, LifecycleEvent和LifecycleListener.
The Lifecycle Interface
Catalina的设计允许一个组件包含其他组件。例如:一个容器可以包含像loader、manager等一样的组件。一个父组件负责启动和停止它的子组件。Catalina的设计让所有组件处于一个父组件监控下,以便一个bootstrap类只需要启动一个单独的组件就可以启动它自己以及它的子组件。这个单独的start/stop机制是通过Lifecycle接口实现的。
在Lifecycle中最重要的方法是start和stop。一个组件提供这些方法的实现,所以它的父组件可以来启动可停止它。其它三个与监听器相关的方法::addLifecycleListener, findLifecycleListeners, 和removeLifecycleListener。一个组件可以有监听器。这些监听器负责监听在这个组件中的事件是否发生。当一个事件触发,监听器会处理这个响应的事件。 这六个事件的名字可以通过一个Lifecycle实例在它接口中定义的public static final Strings来触发。
The LifecycleEvent Class
org.apache.catalina.LifecycleEvent类代表一个生命周期事件:
The LifecycleListener Interface
org.apache.catalina.LifecycleListener接口代表一个生命周期监听器:
这个接口唯一的方法是lifecycleEvent。在一个监听器负责的事件被触发时这个方法会被调用
The LifecycleSupport Class
一个组件实现了Lifecycle,且允许一个监听器注册它相关的事件必须提供事件处理的代码给Lifecycle接口的相关方法:addLifecycleListener, findLifecycleListeners和removeLifecycleListener。然后这个组件必须存储所有的监听器,把它们添加到一个数组或一个ArrayList或类似的对象。Catalina提供一个工具类让一个组件可以很简单地处理监听器和触发生命周期事件:org.apache.catalina.util.LifecycleSupport。
你看见LifecycleSupport类把所有的生命周期监听器存储到一个listeners的数组中,它开始是没有元素的。
当用addLifecycleListener方法添加一个监听器时,会创建一个新的数组。这个数组的元素大小是原数组大小的值加1。然后,原数组的所有元素会被复制到新数组中,这个新的监听器就被添加了。当使用removeLifecycleListener方法移除一个监听器时,也会创建一个新数组,这个数组的大小是原数组大小的值减1。然后,除了被移除的监听器外,其他所有元素会被复制到新数组中。
fireLifecycleEvent方法会触发一个生命周期事件。首先,它克隆监听器数组。然后,它调用数组中每一个成员的lifecycleEvent方法,并传递被触发的事件。
一个组件实现了Lifecycle可以使用LifecycleSupport类。例如, 在本章的应用中的SimpleContext类声明了下面的变量:
要添加一个生命周期监听器,SimpleContext类调用LifecycleSupport类的addLifecycleListener方法:
要移除一个监听器,SimpleContext类调用LifecycleSupport类的removeLifecycleListener方法:
要触发一个事件,SimpleContext类调用LifecycleSupport类的fireLifecycleEvent方法:
The Application
本章的应用程序是建立在第五章的应用程序的基础上,它使用了Lifecycle接口和生命周期相关类型。它包含了一个context和两个wrapper,同样也有一个loader和一个mapper。本应用的这些组件都实现了Lifecycle接口,context使用了一个监听器。为了简化这个应用,我们没有使用那两个valve。下面是类图:
注意SimpleContextLifecycleListener类代表SimpleContext类的一个监听器类。SimpleContextValve, SimpleContextMapper和SimpleWrapperValve类同第五章的是一样的。
ex06.pyrmont.core.SimpleContext
本应用的SimpleContext类除了实现了Lifecycle接口,其他和第五章的相似。SimpleContext类使用下面的变量引用一个LifecycleSupport实例:
它也用一个叫做started的boolean变量,这个变量表明SimpleContext实例是否启动了。SimpleContext类提供了Lifecycle接口方法的实现。
注意start方法是怎么来启动所有的像:Loader、Pipeline、Mapper这样的子容器和与它的相关组件,而stop方法又是怎么来停止它们的呢?使用这种机制来启动容器模块的所有组件,你只需要启动在层次结构中最高层的组件(本例中是SimpleContext实例)。要停止它们,你只需要停止同样的这个单独组件。
在SimpleContext中的start方法的开始要通过检查它是否启动,如果这个组件在之前已经启动了,这时将抛一个LifecycleException异常。
它然后触发BEFORE_START_EVENT事件。
结果,每一个在SimpleContext实例里注册的相关事件监听器将被调用。在这个应用中,一个SimpleContextLifecycleListener类型的监听器注册它的相关事件。
接下来,start方法把started的这个boolean变量设置成true,表明组件被启动了。
然后start方法启动所有组件和它的子容器。当前这里有两个组件,它们都实现了Lifecycle接口。SimpleLoader和SimplePipeline。SimpleContext有两个wrapper作为它的子容器。这两个都是SimpleWrapper类型,它们也都实现了Lifecycle接口。
当所有组件和子容器都启动后,start方法触发这两事件:START_EVENT和 AFTER_START_EVENT.。
这个stop方法首先检查这个实例是否启动了,如果没启动,它抛出一个LifecycleException异常。
它然后触发BEFORE_STOP_EVENT 和STOP_EVENT这两个事件,并设置started这个boolean变量。
接下来,stop方法停止它所有相关组件和SimpleContext实例的子容器。
最后,触发AFTER_STOP_EVENT事件。
ex06.pyrmont.core.SimpleContextLifecycleListener
SimpleContextLifecycleListener类代表一个SimpleContext接口的监听器:
SimpleContextLifecycleListener类的lifecycleEvent方法的实现很简单。它只是简单打印被触发的事件。如果它是一个START_EVENT事件,lifecycleEvent方法打印启动上下文(Starting context)。如果事件是一个STOP_EVENT事件它打印停止上下文(Stopping context)。
ex06.pyrmont.core.SimpleLoader
SimpleLoader类除了实现了Lifecycle接口外,其它的和第五章的类似。Lifecycle接口的方法实现就是在控制台打印字符串。更重要的是,通过实现Lifecycle接口,一个SimpleLoader实例可以通过它的相关容器来启动它。
在SimpleLoader的Lifecycle接口的这些方法:
ex06.pyrmont.core.SimplePipeline
除了实现了Pipeline接口,SimplePipeline类也实现了Lifecycle接口。Lifecycle接口方法的实现是空的,但是现在这个类的实例可以被它相关联的容器来启动。类其它部分跟第五章的SimplePipeline类相同。
ex06.pyrmont.core.SimpleWrapper
这个类和ex05.pyrmont.core.SimpleWrapper类相似。在这个应用,它实现了Lifecycle接口,所以它可以被它的父容器启动。在这个应用程序大多数方法除了start和stop方法,其它方法的实现都为空。
SimpleWrapper的start方法和SimpleContext类的start方法类似。它启动任何添加到它里面的组件。触发BEFORE_START_EVENT, START_EVENT和AFTER_START_EVENT事件。
SimpleWrapper的stop方法更有趣。打印了一个简单的字符串后,它调用servlet实例的destroy方法。
然后,检查wrapper是否启动了,如果没有,它抛出一个LifecycleException异常。
接下来,它触发BEFORE_STOP_EVENT和STOP_EVENT事件。然后设置started这个boolean变量。
接下来,它停止loader和pipeline相关的组件。在这个应用程序,SimpleWrapper实例没有loader。
最后,它触发 AFTER_STOP_EVENT事件。
总结:这章你知道了怎么与Lifecycle接口工作。这个接口定义了一个组件的生命周期和提供了优雅的方式来发送事件给另一个组件。此外,Lifecycle接口也使得使用一个单独的start/stop来启动和停止在Catalina的所有组件变得可能。
第六章 完
Catalina是由许多组件组成的。当Catalina启动时,这些组件也需要跟着启动。当Catalina停止,这些组件也必须得到被清理的机会。例如,当一个容器停止,它必须调用加载了的所有的servlet的destroy方法,session管理器必须把session对象保存到辅助存储器。一个统一的用来启动和停止组件的机制是通过实现org.apache.catalina.Lifecycle接口。
一个实现了Lifecycle接口的组件可以触发一个或许多事件:BEFORE_START_EVENT, START_EVENT, AFTER_START_EVENT, BEFORE_STOP_EVENT, STOP_EVENT和AFTER_STOP_EVENT。当通常一个启动组件时触发前三个事件,当停止组件时触发三个事件。一个事件由org.apache.catalina.LifecycleEvent类代表。最后,当然,如果一个Catalina组件想要能够触发事件,这里必须有事件监听器。事件监听器让你来处理这些事件的响应。一个监听器由org.apache.catalina.LifecycleListener接口代表。
这章将讨论Lifecycle, LifecycleEvent和LifecycleListener.
The Lifecycle Interface
Catalina的设计允许一个组件包含其他组件。例如:一个容器可以包含像loader、manager等一样的组件。一个父组件负责启动和停止它的子组件。Catalina的设计让所有组件处于一个父组件监控下,以便一个bootstrap类只需要启动一个单独的组件就可以启动它自己以及它的子组件。这个单独的start/stop机制是通过Lifecycle接口实现的。
Listing 6.1: The Lifecycle interface package org.apache.catalina; public interface Lifecycle { public static final String START_EVENT = "start"; public static final String BEFORE_START_EVENT = "before_start"; public static final String AFTER_START_EVENT = "after_start"; public static final String STOP_EVENT = "stop"; public static final String BEFORE_STOP_EVENT = "before_stop"; public static final String AFTER_STOP_EVENT = "after_stop"; public void addLifecycleListener(LifecycleListener listener); public LifecycleListener[] findLifecycleListeners(); public void removeLifecycleListener(LifecycleListener listener); public void start() throws LifecycleException; public void stop() throws LifecycleException; }
在Lifecycle中最重要的方法是start和stop。一个组件提供这些方法的实现,所以它的父组件可以来启动可停止它。其它三个与监听器相关的方法::addLifecycleListener, findLifecycleListeners, 和removeLifecycleListener。一个组件可以有监听器。这些监听器负责监听在这个组件中的事件是否发生。当一个事件触发,监听器会处理这个响应的事件。 这六个事件的名字可以通过一个Lifecycle实例在它接口中定义的public static final Strings来触发。
The LifecycleEvent Class
org.apache.catalina.LifecycleEvent类代表一个生命周期事件:
Listing 6.2: The org.apache.catalinaLifecycleEvent interface package org.apache.catalina; import java.util.EventObject; public final class LifecycleEvent extends EventObject { public LifecycleEvent(Lifecycle lifecycle, String type) { this(lifecycle, type, null); } public LifecycleEvent(Lifecycle lifecycle, String type, Object data) { super(lifecycle); this.lifecycle = lifecycle; this.type = type; this.data = data; } private Object data = null; private Lifecycle lifecycle = null; private String type = null; public Object getData() { return (this.data); } public Lifecycle getLifecycle() { return (this.lifecycle); } public String getType() { return (this.type); } }
The LifecycleListener Interface
org.apache.catalina.LifecycleListener接口代表一个生命周期监听器:
Listing 6.3: The org.apache.catalina.LifecycleListener interface package org.apache.catalina; import java.util.EventObject; public interface LifecycleListener { public void lifecycleEvent(LifecycleEvent event); }
这个接口唯一的方法是lifecycleEvent。在一个监听器负责的事件被触发时这个方法会被调用
The LifecycleSupport Class
一个组件实现了Lifecycle,且允许一个监听器注册它相关的事件必须提供事件处理的代码给Lifecycle接口的相关方法:addLifecycleListener, findLifecycleListeners和removeLifecycleListener。然后这个组件必须存储所有的监听器,把它们添加到一个数组或一个ArrayList或类似的对象。Catalina提供一个工具类让一个组件可以很简单地处理监听器和触发生命周期事件:org.apache.catalina.util.LifecycleSupport。
Listing 6.4: The LifecycleSupport class package org.apache.catalina.util; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleEvent; import org.apache.catalina.LifecycleListener; public final class LifecycleSupport { public LifecycleSupport(Lifecycle lifecycle) { super(); this.lifecycle = lifecycle; } private Lifecycle lifecycle = null; private LifecycleListener listeners[] = new LifecycleListener[0]; public void addLifecycleListener(LifecycleListener listener) { synchronized (listeners) { LifecycleListener results[] = new LifecycleListener[listeners.length + 1]; for (int i = 0; i < listeners.length; i++) results[i] = listeners[i]; results[listeners.length] = listener; listeners = results; } } public LifecycleListener[] findLifecycleListeners() { return listeners; } public void fireLifecycleEvent(String type, Object data) { LifecycleEvent event = new LifecycleEvent(lifecycle, type, data); LifecycleListener interested[] = null; synchronized (listeners) { interested = (LifecycleListener[]) listeners.clone(); } for (int i = 0; i < interested.length; i++) interested[i].lifecycleEvent(event); } public void removeLifecycleListener(LifecycleListener listener) { synchronized (listeners) { int n = -1; for (int i = 0; i < listeners.length; i++) { if (listeners[i] == listener) { n = i; break; } } if (n < 0) return; LifecycleListener results[] = new LifecycleListener[listeners.length - 1]; int j = 0; for (int i = 0; i < listeners.length; i++) { if (i != n) results[j++] = listeners[i]; } listeners = results; } } }
你看见LifecycleSupport类把所有的生命周期监听器存储到一个listeners的数组中,它开始是没有元素的。
private LifecycleListener listeners[] = new LifecycleListener[0];
当用addLifecycleListener方法添加一个监听器时,会创建一个新的数组。这个数组的元素大小是原数组大小的值加1。然后,原数组的所有元素会被复制到新数组中,这个新的监听器就被添加了。当使用removeLifecycleListener方法移除一个监听器时,也会创建一个新数组,这个数组的大小是原数组大小的值减1。然后,除了被移除的监听器外,其他所有元素会被复制到新数组中。
fireLifecycleEvent方法会触发一个生命周期事件。首先,它克隆监听器数组。然后,它调用数组中每一个成员的lifecycleEvent方法,并传递被触发的事件。
一个组件实现了Lifecycle可以使用LifecycleSupport类。例如, 在本章的应用中的SimpleContext类声明了下面的变量:
protected LifecycleSupport lifecycle = new LifecycleSupport(this);
要添加一个生命周期监听器,SimpleContext类调用LifecycleSupport类的addLifecycleListener方法:
public void addLifecycleListener(LifecycleListener listener) { lifecycle.addLifecycleListener(listener); }
要移除一个监听器,SimpleContext类调用LifecycleSupport类的removeLifecycleListener方法:
public void removeLifecycleListener(LifecycleListener listener) { lifecycle.removeLifecycleListener(listener); }
要触发一个事件,SimpleContext类调用LifecycleSupport类的fireLifecycleEvent方法:
lifecycle.fireLifecycleEvent(START_EVENT, null);
The Application
本章的应用程序是建立在第五章的应用程序的基础上,它使用了Lifecycle接口和生命周期相关类型。它包含了一个context和两个wrapper,同样也有一个loader和一个mapper。本应用的这些组件都实现了Lifecycle接口,context使用了一个监听器。为了简化这个应用,我们没有使用那两个valve。下面是类图:
注意SimpleContextLifecycleListener类代表SimpleContext类的一个监听器类。SimpleContextValve, SimpleContextMapper和SimpleWrapperValve类同第五章的是一样的。
ex06.pyrmont.core.SimpleContext
本应用的SimpleContext类除了实现了Lifecycle接口,其他和第五章的相似。SimpleContext类使用下面的变量引用一个LifecycleSupport实例:
protected LifecycleSupport lifecycle = new LifecycleSupport(this);
它也用一个叫做started的boolean变量,这个变量表明SimpleContext实例是否启动了。SimpleContext类提供了Lifecycle接口方法的实现。
Listing 6.5: Methods from the Lifecycle interface. public void addLifecycleListener(LifecycleListener listener) { lifecycle.addLifecycleListener(listener); } public LifecycleListener[] findLifecycleListeners() { return null; } public void removeLifecycleListener(LifecycleListener listener) { lifecycle.removeLifecycleListener(listener); } public synchronized void start() throws LifecycleException { if (started) throw new LifecycleException("SimpleContext has already started"); // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null); started = true; try { // Start our subordinate components, if any if ((loader != null) && (loader instanceof Lifecycle)) ((Lifecycle) loader).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 the basic), // if any if (pipeline instanceof Lifecycle) ((Lifecycle) pipeline).start(); // Notify our Interested LifecycleListeners lifecycle.firelifecycleEvent(START_EVENT, null); } catch (Exception e) { e.printStackTrace(); } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null); } public void stop() throws LifecycleException { if (!started) throw new LifecycleException("SimpleContext has not been started"); // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null); lifecycle.fireLifecycleEvent(STOP_EVENT, null); started = false; try { // Stop the Valves in our pipeline (including the basic), if any if (pipeline instanceof Lifecycle) ( ((Lifecycle) pipeline).stop(); } // Stop our child containers, if any Container children[] = findChildren(); for (int i = 0; i < children.length; i++) { if (children[i] instanceof Lifecycle) ((Lifecycle) children[i]).stop(); } if ((loader != null) && (loader instanceof Lifecycle)) { ((Lifecycle) loader).stop(); } } catch (Exception e) { e.printStackTrace(); } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null); }
注意start方法是怎么来启动所有的像:Loader、Pipeline、Mapper这样的子容器和与它的相关组件,而stop方法又是怎么来停止它们的呢?使用这种机制来启动容器模块的所有组件,你只需要启动在层次结构中最高层的组件(本例中是SimpleContext实例)。要停止它们,你只需要停止同样的这个单独组件。
在SimpleContext中的start方法的开始要通过检查它是否启动,如果这个组件在之前已经启动了,这时将抛一个LifecycleException异常。
if (started) throw new LifecycleException( "SimpleContext has already started");
它然后触发BEFORE_START_EVENT事件。
// Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
结果,每一个在SimpleContext实例里注册的相关事件监听器将被调用。在这个应用中,一个SimpleContextLifecycleListener类型的监听器注册它的相关事件。
接下来,start方法把started的这个boolean变量设置成true,表明组件被启动了。
started = true;
然后start方法启动所有组件和它的子容器。当前这里有两个组件,它们都实现了Lifecycle接口。SimpleLoader和SimplePipeline。SimpleContext有两个wrapper作为它的子容器。这两个都是SimpleWrapper类型,它们也都实现了Lifecycle接口。
try { // Start our subordinate components, if any if ((loader != null) && (loader instanceof Lifecycle)) ((Lifecycle) loader).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 the basic), // if any if (pipeline instanceof Lifecycle) ((Lifecycle) pipeline).start();
当所有组件和子容器都启动后,start方法触发这两事件:START_EVENT和 AFTER_START_EVENT.。
// Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(START_EVENT, null); . // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
这个stop方法首先检查这个实例是否启动了,如果没启动,它抛出一个LifecycleException异常。
if (!started) throw new LifecycleException( "SimpleContext has not been started");
它然后触发BEFORE_STOP_EVENT 和STOP_EVENT这两个事件,并设置started这个boolean变量。
// Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null); lifecycle.fireLifecycleEvent(STOP_EVENT, null); started = false;
接下来,stop方法停止它所有相关组件和SimpleContext实例的子容器。
try { // Stop the Valves in our pipeline (including the basic), if any if (pipeline instanceof Lifecycle) { ((Lifecycle) pipeline).stop(); } // Stop our child containers, if any Container children[] = findChildren(); for (int i = 0; i < children.length; i++) { if (children[i] instanceof Lifecycle) ((Lifecycle) children[i]).stop(); } if ((loader != null) && (loader instanceof Lifecycle)) { ((Lifecycle) loader).stop(); } }
最后,触发AFTER_STOP_EVENT事件。
// Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
ex06.pyrmont.core.SimpleContextLifecycleListener
SimpleContextLifecycleListener类代表一个SimpleContext接口的监听器:
Listing 6.6: The SimpleContextLifecycleListener class package ex06.pyrmont.core; import org.apache.catalina.Context; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleEvent; import org.apache.catalina.LifecycleListener; public class SimpleContextLifecycleListener implements LifecycleListener { public void lifecycleEvent(LifecycleEvent event) { Lifecycle lifecycle = event.getLifecycle(); System.out.println("SimpleContextLifecycleListener's event " + event.getType().toString()); if (Lifecycle.START_EVENT.equals(event.getType())) { System.out.println("Starting context."); } else if (Lifecycle.STOP_EVENT.equals(event.getType())) { System.out.println("Stopping context."); } } }
SimpleContextLifecycleListener类的lifecycleEvent方法的实现很简单。它只是简单打印被触发的事件。如果它是一个START_EVENT事件,lifecycleEvent方法打印启动上下文(Starting context)。如果事件是一个STOP_EVENT事件它打印停止上下文(Stopping context)。
ex06.pyrmont.core.SimpleLoader
SimpleLoader类除了实现了Lifecycle接口外,其它的和第五章的类似。Lifecycle接口的方法实现就是在控制台打印字符串。更重要的是,通过实现Lifecycle接口,一个SimpleLoader实例可以通过它的相关容器来启动它。
在SimpleLoader的Lifecycle接口的这些方法:
Listing 6.7: The methods from Lifecycle in the SimpleLoader class public void addLifecycleListener(LifecycleListener listener) { } public LifecycleListener[] findLifecycleListeners() { return null; } public void removeLifecycleListener(LifecycleListener listener) { } public synchronized void start() throws LifecycleException { System.out.println("Starting SimpleLoader"); } public void stop() throws LifecycleException { }
ex06.pyrmont.core.SimplePipeline
除了实现了Pipeline接口,SimplePipeline类也实现了Lifecycle接口。Lifecycle接口方法的实现是空的,但是现在这个类的实例可以被它相关联的容器来启动。类其它部分跟第五章的SimplePipeline类相同。
ex06.pyrmont.core.SimpleWrapper
这个类和ex05.pyrmont.core.SimpleWrapper类相似。在这个应用,它实现了Lifecycle接口,所以它可以被它的父容器启动。在这个应用程序大多数方法除了start和stop方法,其它方法的实现都为空。
Listing 6.8: The methods from the Lifecycle interface public void addLifecycleListener(LifecycleListener listener) { } public LifecycleListener[] findLifecycleListeners() { return null; } public void removeLifecycleListener(LifecycleListener listener) ( } public synchronized void start() throws LifecycleException { System.out.println("Starting Wrapper " + name); if (started) throw new LifecycleException("Wrapper already started"); // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null); started = true; // Start our subordinate components, if any if ((loader != null) && (loader instanceof Lifecycle)) ((Lifecycle) loader).start(); // Start the Valves in our pipeline (including the basic), if any if (pipeline instanceof Lifecycle) ((Lifecycle) pipeline).start(); // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(START_EVENT, null); // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null); } public void stop() throws LifecycleException { System.out.println("Stopping wrapper " + name); // Shut down our servlet instance (if it has been initialized) try { instance.destroy(); } catch (Throwable t) { } instance = null; if (!started) throw new LifecycleException("Wrapper " + name + " not started"); // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null); // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(STOP_EVENT, null); started = false; // Stop the Valves in our pipeline (including the basic), if any if (pipeline instanceof Lifecycle) { ((Lifecycle) pipeline).stop(); } // Stop our subordinate components, if any if ((loader != null) && (loader instanceof Lifecycle)) { ((Lifecycle) loader).stop(); } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null); }
SimpleWrapper的start方法和SimpleContext类的start方法类似。它启动任何添加到它里面的组件。触发BEFORE_START_EVENT, START_EVENT和AFTER_START_EVENT事件。
SimpleWrapper的stop方法更有趣。打印了一个简单的字符串后,它调用servlet实例的destroy方法。
System.out.println("Stopping wrapper " + name); // Shut down our servlet instance (if it has been initialized) try { instance.destroy(); } catch (Throwable t) { } instance = null;
然后,检查wrapper是否启动了,如果没有,它抛出一个LifecycleException异常。
if (!started) throw new LifecycleException("Wrapper " + name + " not started");
接下来,它触发BEFORE_STOP_EVENT和STOP_EVENT事件。然后设置started这个boolean变量。
// Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null); // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(STOP_EVENT, null); started = false;
接下来,它停止loader和pipeline相关的组件。在这个应用程序,SimpleWrapper实例没有loader。
// Stop the Valves in our pipeline (including the basic), if any if (pipeline instanceof Lifecycle) { ((Lifecycle) pipeline).stop(); } // Stop our subordinate components, if any if ((loader != null) && (loader instanceof Lifecycle)) { ((Lifecycle) loader).stop(); }
最后,它触发 AFTER_STOP_EVENT事件。
// Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
总结:这章你知道了怎么与Lifecycle接口工作。这个接口定义了一个组件的生命周期和提供了优雅的方式来发送事件给另一个组件。此外,Lifecycle接口也使得使用一个单独的start/stop来启动和停止在Catalina的所有组件变得可能。
第六章 完
发表评论
-
MyEclipse插件安装
2012-03-22 10:05 4321:先把plugin的jar文件复制到一个文件夹下 如:C:/ ... -
Hibernate框架使用技术简述
2011-03-24 10:14 1132(1)持久化对象的操 ... -
Coder 爱翻译 How Tomcat Works 第九章 第二部分
2011-01-24 15:20 1171The ManagerBase Class ManagerB ... -
Coder 爱翻译 How Tomcat Works 第九章 第一部分
2010-12-16 20:40 1264Chapter 9: Session Management ... -
Coder 爱翻译 How Tomcat Works 第八章 第二部分
2010-12-12 18:31 1517The Loader Interface 在web应 ... -
Coder 爱翻译 How Tomcat Works 第八章 第一部分
2010-12-06 11:14 1097Chapter 8: Loader 在前几章 ... -
Coder 爱翻译 How Tomcat Works 第七章
2010-12-05 16:29 1189Chapter 7: Logger 日志是一 ... -
Coder 爱翻译 How Tomcat Works 第五章 第三部分
2010-12-03 13:31 1154The Context Application 这章的第一个 ... -
Coder 爱翻译 How Tomcat Works 第五章 第二部分
2010-12-03 12:33 3108The Pipeline Interface 我们提到的Pi ... -
Coder 爱翻译 How Tomcat Works 第五章 第一部分
2010-11-28 16:36 1170Chapter 5: Container 一个容器是一个为s ... -
Coder 爱翻译 How Tomcat Works 第四章 第二部分
2010-11-27 15:07 1058Request Objects 在默认的连接器中org.ap ... -
Coder 爱翻译 How Tomcat Works 第四章 第一部分
2010-11-25 16:38 948Chapter 4: Tomcat Default Conne ... -
PreparedStatement字符串拼接
2010-11-18 17:21 1406这在里求JDBC中PreparedStatement的实现,我 ... -
HelloWorld的javap -verbose HelloWorld 字节码初探
2010-11-17 12:20 3124基本的HelloWorld类: public class ... -
How Tomcat Works 简单目录
2010-11-16 14:51 1444第1章:通过一个简单的HTTP服务器开始这本书的内容。构建一个 ... -
Coder 爱翻译 How Tomcat Works 第三章 第三部分
2010-11-15 19:24 1034Parsing Headers 一个HttpHeader类 ... -
Coder 爱翻译 How Tomcat Works 第三章 第二部分
2010-11-14 20:13 1093The Connector(连接器) HttpConnect ... -
回应某面试题
2010-11-10 21:31 1323上午看了一JAVAEYE的一个上机题:http://www.i ... -
quartz简单应用
2010-11-10 11:49 1001Job类:实现Job接口,接口中有一个execute()方法, ... -
coder 爱翻译 How Tomcat Works 第三章 第一部分
2010-11-05 11:41 1132第三章: Connector 在正式 ...
相关推荐
适合读者 1.jsp/servlet 开发人员,想了解 tomcat 内部机制的 coder; 2.想加入 tomcat 开发团队的 coder; 3.web 开发人员,但对软件开发很有兴趣的 coder; 4.想要对 tomcat 进行定制的 coder。
Bad Programming Practices 101 Become a Better Coder by Learning How (Not) to Program 英文epub 本资源转载自网络,如有侵权,请联系上传者或csdn删除 查看此书详细信息请在美国亚马逊官网搜索此书
mediacoder 5685专业版,无普通版的限制
- **插件扩展**:PHPCoder支持第三方插件,可以通过社区下载安装增强功能。 - **代码格式化**:使用“编辑”>“格式化代码”对代码进行整理,保持良好的编码风格。 - **搜索与替换**:利用查找和替换功能,可以在...
6. 插件扩展:MediaCoder有一个开放的插件架构,用户可以通过安装第三方插件来增加新的编码解码器、滤镜和其他功能,扩展其应用范围。 7. 用户友好:MediaCoder的界面简洁直观,即便是对编码不熟悉的用户也能快速...
Embedded Coder用于产生嵌入式处理器、目标快速原型板和大规模生产中使用的微处理器的可读的、紧凑的、快速的C和C++代码。Embedded Coder支持附加的MATLAB Coder™和Simulink Coder™配置选项,以及对生成代码的功能...
#### 六、Simulink HDL Coder 使用技巧 1. **模型规范化**:在设计模型时遵循一定的规范,如避免使用非线性操作或复杂函数,这有助于提高代码生成的质量。 2. **参数化设计**:使用 MATLAB 函数和 Simulink 参数...
Prentice Hall | 2011 | ISBN: 0137081073 | 256 pages | PDF | 6 MB Programmers who endure and succeed amidst swirling uncertainty and nonstop pressure share a common attribute: They care deeply about ...
**Mediacoder基础教程** Mediacoder是一款强大的多媒体编码工具,专为音频和视频转换而设计,支持多种格式,如MP4、AVI、MKV等。本教程将深入讲解如何利用Mediacoder进行视频压制,优化视频质量,同时合理权衡码率...
6. **提高开发效率**: 使用CoolCoder,开发者可以从繁重的手动编码工作中解脱出来,将更多精力投入到业务逻辑的设计和优化中,从而提升整体项目的开发效率。 综上所述,CoolCoder类生成工具是现代开发环境下的一...
### HDL-Coder详细教程知识点概述 #### 一、生成HDL代码前的准备工作 在开始从Simulink模型生成HDL代码之前,需要完成一系列的准备工作,确保模型能够顺利生成高质量的代码。 ##### 1.1 使用`hdlsetup`进行模型...
PHPCoder用于快速开发和调试PHP应用程序,它很容易扩展和定制,完全能够符合开发者的个性要求.PHPCoder是一个非常实用的,功能强大的编程环境,而且它是免费的!
### MATLAB Coder 基本函数教程 #### MATLAB Coder 概述 MATLAB Coder 是一款能够将 MATLAB 代码转换成独立的 C 或 C++ 代码的强大工具。这一过程对于那些希望在非 MATLAB 环境下部署 MATLAB 代码的应用开发者来说...
MediaCoder行业版一款针对VOD及KTV视频点播行业开发的,用于转换和处理带有多音轨内容的视频节目的软件。它具备业界领先的视频编码引擎,在高性能转码的同时保持高画质,并通过丰富的视频滤镜增强画面视觉效果。作为...
MediaCoder是一款功能强大的多媒体转换工具,它支持广泛的音频和视频编码格式,使用户能够轻松地在不同设备之间转换媒体文件。这款软件适用于个人用户、专业音频和视频制作人员,以及那些希望在各种设备上享受多媒体...
Matlab Coder是Mathworks公司推出的一款用于将Matlab代码转换成高效C代码的工具。从2004年开始,Matlab陆续在Simulink中添加了Embeded Matlab Function模块,2007年在Real-Time Workshop中引入了emlc函数(现在的...
texasinstrumentsc2000.mlpkginstall 支持TI的C2000系列工具包,要求MATLAB R2017a及其以上版本。 安装方法:打开matlab,调整路径到mlpkginstall文件所在目录;在current folder窗口里双击mlpkginstall文件即可开始...
开源的AI自动生成SQL语句源代码,这款SQLCoder-70B-Alpha在文本到SQL的转换能力上超越了包括GPT-4在内的所有通用模型,它能更准确地理解你的需求,并生成相应的SQL查询。SQLCoder2和SQLCoder-7B模型已经向公众开放,...
MediaCoder-Premium-x64 MediaCoder是最早开始使用GPU进行视频编码加速的影音转码软件之一。通过将原本完全依赖CPU的计算工作转移到GPU上进行,H.264和H.265编码所需的时间被大幅缩短。