浅析Tomcat之Lifecycle

  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[i] = listeners[i];
          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[i].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[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对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

猜你喜欢

转载自lihkstyle.iteye.com/blog/1944392
今日推荐