设为首页 收藏本站
查看: 402|回复: 0

[经验分享] 浅析Tomcat之Lifecycle

[复制链接]

尚未签到

发表于 2017-1-24 10:55:41 | 显示全部楼层 |阅读模式
    Tomcat很多组件都有其生命周期,比如:StandardServer,StandardService等.这个生命周期用来控制组件的资源情况.在Tomcat的生命周期管理中主要体现在接口Lifecycle,LifecycleListener及其相关类LifecycleEvent.这个实现方式是典型的观察者模式.顾名思义,实现Lifecycle接口的是被观察的对象,而实现LifecycleListener接口的是观察者.而LifecycleEvent是中间传递事件和数据的对象.

我们可以先看看Lifecycle和LifecycleListener的代码.

public interface Lifecycle
{
public static final String BEFORE_INIT_EVENT = "before_init";
public static final String AFTER_INIT_EVENT = "after_init";
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 static final String AFTER_DESTROY_EVENT = "after_destroy";
public static final String BEFORE_DESTROY_EVENT = "before_destroy";
public static final String PERIODIC_EVENT = "periodic";
public static final String CONFIGURE_START_EVENT = "configure_start";
public static final String CONFIGURE_STOP_EVENT = "configure_stop";
public void addLifecycleListener(LifecycleListener listener);
public LifecycleListener[] findLifecycleListeners();
public void removeLifecycleListener(LifecycleListener listener);
public void init() throws LifecycleException;
public void start() throws LifecycleException;
public void stop() throws LifecycleException;
public void destroy() throws LifecycleException;
public LifecycleState getState();
public String getStateName();
}
public interface LifecycleListener
{
public void lifecycleEvent(LifecycleEvent event);
}

  Lifecycle接口所规范的是生命周期组件所拥有的生命周期内的状态和所拥有的操作.如初始化,启动停止和销毁.以及添加观察者.而接口LifecycleListener 规范的是观察者在生命周期组件的状态发生变化的时候所触发的处理内容.这样就足以构成观察者模式.但是Tomcat实现了一个LifecycleSupport的工具类方便了生命周期类的编写.

public final class LifecycleSupport
{
public LifecycleSupport(Lifecycle lifecycle) {
super();
this.lifecycle = lifecycle;
}
private Lifecycle lifecycle = null;
/**
* The set of registered LifecycleListeners for event notifications.
*/
private LifecycleListener listeners[] = new LifecycleListener[0];
// Lock object for changes to listeners
private final Object listenersLock = new Object();
/**
* Add a lifecycle event listener to this component.
*
* @param listener The listener to add
*/
public void addLifecycleListener(LifecycleListener listener) {
synchronized (listenersLock) {
LifecycleListener results[] =
new LifecycleListener[listeners.length + 1];
for (int i = 0; i < listeners.length; i++)
results = listeners;
results[listeners.length] = listener;
listeners = results;
}
}
/**
* Get the lifecycle listeners associated with this lifecycle. If this
* Lifecycle has no listeners registered, a zero-length array is returned.
*/
public LifecycleListener[] findLifecycleListeners() {
return listeners;
}
/**
* Notify all lifecycle event listeners that a particular event has
* occurred for this Container.  The default implementation performs
* this notification synchronously using the calling thread.
*
* @param type Event type
* @param data Event data
*/
public void fireLifecycleEvent(String type, Object data) {
LifecycleEvent event = new LifecycleEvent(lifecycle, type, data);
LifecycleListener interested[] = listeners;
for (int i = 0; i < interested.length; i++)
interested.lifecycleEvent(event);
}
/**
* Remove a lifecycle event listener from this component.
*
* @param listener The listener to remove
*/
public void removeLifecycleListener(LifecycleListener listener) {
synchronized (listenersLock) {
int n = -1;
for (int i = 0; i < listeners.length; i++) {
if (listeners == 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;
}
listeners = results;
}
}
}

     LifecycleSupport对Lifecycle做了一些基础的实现.它持有一个LifecycleListener的数组.这个数组用来存储所有注册的观察者.除了提供了基本的实现,还实现了一个重要的函数fireLifecycleEvent.它触发了所有listener的lifecycleEvent.所以使用的时候可以直接fireLifecycleEvent.这个类的基本用法是让生命周期组件直接持有类的对象.然后实现Liftcycle接口,基本方法的实现基本上可以通过这对象来代劳.同样Tomcat也实现了这样一个虚类叫LifecycleBase.这个类在Tomcat中成为了所有生命周期组件的基类.它的存在方便了生命周期管理代码的编写.

public abstract class LifecycleBase implements Lifecycle
{//省略很多其他代码
private LifecycleSupport lifecycle = new LifecycleSupport(this);
public void addLifecycleListener(LifecycleListener listener) {
lifecycle.addLifecycleListener(listener);
}
public LifecycleListener[] findLifecycleListeners() {
return lifecycle.findLifecycleListeners();
}
public void removeLifecycleListener(LifecycleListener listener) {
lifecycle.removeLifecycleListener(listener);
}
protected void fireLifecycleEvent(String type, Object data) {
lifecycle.fireLifecycleEvent(type, data);
}
}

       上述观察者的实现在JDK中也有类似思想的存在.那就是PropertyChangeSupport.这边顺便mark一下.PropertyChangeSupport是用来监听bean属性发生变化的.在Tomcat7实现中也有用到该类.这边给出一个使用的实例.

public class Property1ChangeListener implements PropertyChangeListener
{
public void propertyChange(PropertyChangeEvent evt)
{
System.out.println("Catch the event in Property1ChangeListener!");
if(evt.getPropertyName().equals("property1"))
{
Object oldValue = evt.getOldValue();
Object newValue = evt.getNewValue();
System.out.println("Old Value:"+oldValue+" ------- New Value:"+newValue);
}
}
}
public class Property2ChangeListener implements PropertyChangeListener
{
public void propertyChange(PropertyChangeEvent evt)
{
System.out.println("Catch the event in Property2ChangeListener!");
if(evt.getPropertyName().equals("property2"))
{
Object oldValue = evt.getOldValue();
Object newValue = evt.getNewValue();
System.out.println("Old Value:"+oldValue+" ------- New Value:"+newValue);
}
}
}
public class PropertyChangeBean
{
private PropertyChangeSupport support = new PropertyChangeSupport(this);
private String property1;
private String property2;
public String getProperty1()
{
return property1;
}
public void setProperty1(String property1)
{
String p = this.property1;
this.property1 = property1;
support.firePropertyChange("property1", p, property1);
}
public String getProperty2()
{
return property2;
}
public void setProperty2(String property2)
{
String p = this.property2;
this.property2 = property2;
support.firePropertyChange("property2", p, property2);
}
public void addPropertyChangeListener(PropertyChangeListener listener)
{
support.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener)
{
support.removePropertyChangeListener(listener);
}
}
public class TestCase
{
public static void main(String[] args)
{
PropertyChangeBean p1 = new PropertyChangeBean();
p1.addPropertyChangeListener(new Property1ChangeListener());
p1.addPropertyChangeListener(new Property2ChangeListener());
PropertyChangeBean p2 = new PropertyChangeBean();
p2.addPropertyChangeListener(new Property1ChangeListener());
p1.setProperty1("1");
p1.setProperty2("1");
p2.setProperty1("1");
p2.setProperty2("1");
}
}

    上述代码中Property1ChangeListener是属性1的观察者类而Property2ChangeListener是属性2的观察者类.PropertyChangeBean是被观察者.在TestCase中观察者被注册到PropertyChangeBean的对象中.当这个对象的属性发生变化时被观察者便会做出相应的反应.Tomcat的LifecycleSupport和JDK的PropertyChangeSupport在实现上是异曲同工的.
  首发于泛泛之辈 - http://www.lihongkun.com/archives/87

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-332889-1-1.html 上篇帖子: tomcat web.xml详细介绍 下篇帖子: Tomcat 配置JNDI服务
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表