我们先阅读图1,从中了解Tomcat涉及生命周期管理的主要类。
图2 JMX架构
/** * Allow sub classes to fire {@link Lifecycle} events. * * @param type Event type * @param data Data associated with event. */ protected void fireLifecycleEvent(String type, Object data) { lifecycle.fireLifecycleEvent(type, data); }lifecycle的定义如下:
/** * Used to handle firing lifecycle events. * TODO: Consider merging LifecycleSupport into this class. */ private LifecycleSupport lifecycle = new LifecycleSupport(this);LifecycleSupport的fireLifecycleEvent方法的实现,见代码清单2。
/** * 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. gja * * @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); }代码清单2将事件通知给所有监听当前容器的生命周期监听器LifecycleListener,并调用LifecycleListener的lifecycleEvent方法。每个容器都维护这一个监听器缓存,其实现如下:
/** * The set of registered LifecycleListeners for event notifications. */ private LifecycleListener listeners[] = new LifecycleListener[0];那么listeners中的监听器是何时添加进来的呢?每个容器在新建、初始化、启动,销毁,被添加到父容器的过程中都会调用父类LifecycleBase的addLifecycleListener方法,addLifecycleListener的实现见代码清单3。
@Override public void addLifecycleListener(LifecycleListener listener) { lifecycle.addLifecycleListener(listener); }从代码清单3看到,LifecycleBase的addLifecycleListener方法实际是对LifecycleSupport的addLifecycleListener方法的简单代理,LifecycleSupport的addLifecycleListener方法的实现,见代码清单4。
/** * 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; } }在代码清单2中,我们讲过容器会最终调用每个对此容器感兴趣的LifecycleListener的lifecycleEvent方法,那么LifecycleListener的lifecycleEvent方法会做些什么呢?为了简单起见,我们以监听器AprLifecycleListener为例,AprLifecycleListener的lifecycleEvent方法的实现,见代码清单5。
/** * Primary entry point for startup and shutdown events. * * @param event The event that has occurred */ public void lifecycleEvent(LifecycleEvent event) { if (Lifecycle.INIT_EVENT.equals(event.getType())) { synchronized (lock) { init(); if (aprAvailable) { try { initializeSSL(); } catch (Throwable t) { log.info(sm.getString("aprListener.sslInit")); } } } } else if (Lifecycle.AFTER_STOP_EVENT.equals(event.getType())) { synchronized (lock) { if (!aprAvailable) { return; } try { terminateAPR(); } catch (Throwable t) { log.info(sm.getString("aprListener.aprDestroy")); } } } }
/** * The current state of the source component. */ private volatile LifecycleState state = LifecycleState.NEW;
public synchronized final void init() throws LifecycleException { if (!state.equals(LifecycleState.NEW)) { invalidTransition(Lifecycle.INIT_EVENT); } initInternal(); setState(LifecycleState.INITIALIZED); }
@Override protected void initInternal() throws LifecycleException { super.initInternal(); // Register global String cache geng // Note although the cache is global, if there are multiple Servers // present in the JVM (may happen when embedding) then the same cache // will be registered under multiple names onameStringCache = register(new StringCache(), "type=StringCache"); // Register the MBeanFactory onameMBeanFactory = register(new MBeanFactory(), "type=MBeanFactory"); // Register the naming resources onameNamingResoucres = register(globalNamingResources, "type=NamingResources"); // Initialize our defined Services for (int i = 0; i < services.length; i++) { services[i].init(); } }
@Override protected void initInternal() throws LifecycleException { // If oname is not null then registration has already happened via jiaan // preRegister(). if (oname == null) { mserver = Registry.getRegistry(null, null).getMBeanServer(); oname = register(this, getObjectNameKeyProperties()); } }
@Override protected final String getObjectNameKeyProperties() { return "type=Server"; }
protected final ObjectName register(Object obj, String objectNameKeyProperties) { // Construct an object name with the right domain StringBuilder name = new StringBuilder(getDomain()); name.append(':'); name.append(objectNameKeyProperties); ObjectName on = null; try { on = new ObjectName(name.toString()); Registry.getRegistry(null, null).registerComponent(obj, on, null); } catch (MalformedObjectNameException e) { log.warn(sm.getString("lifecycleMBeanBase.registerFail", obj, name), e); } catch (Exception e) { log.warn(sm.getString("lifecycleMBeanBase.registerFail", obj, name), e); } return on; }
/** Register a component * XXX make it private * * @param bean * @param oname * @param type * @throws Exception */ public void registerComponent(Object bean, ObjectName oname, String type) throws Exception { if( log.isDebugEnabled() ) { log.debug( "Managed= "+ oname); } if( bean ==null ) { log.error("Null component " + oname ); return; } try { if( type==null ) { type=bean.getClass().getName(); } ManagedBean managed = findManagedBean(bean.getClass(), type); // The real mbean is created and registered DynamicMBean mbean = managed.createMBean(bean); if( getMBeanServer().isRegistered( oname )) { if( log.isDebugEnabled()) { log.debug("Unregistering existing component " + oname ); } getMBeanServer().unregisterMBean( oname ); } getMBeanServer().registerMBean( mbean, oname); } catch( Exception ex) { log.error("Error registering " + oname, ex ); throw ex; } }
@Override public synchronized final void start() throws LifecycleException { if (LifecycleState.STARTING_PREP.equals(state) || LifecycleState.STARTING.equals(state) || LifecycleState.STARTED.equals(state)) { if (log.isDebugEnabled()) { Exception e = new LifecycleException(); log.debug(sm.getString("lifecycleBase.alreadyStarted", toString()), e); } else if (log.isInfoEnabled()) { log.info(sm.getString("lifecycleBase.alreadyStarted", toString())); } return; } if (state.equals(LifecycleState.NEW)) { init(); } else if (!state.equals(LifecycleState.INITIALIZED) && !state.equals(LifecycleState.STOPPED)) { invalidTransition(Lifecycle.BEFORE_START_EVENT); } setState(LifecycleState.STARTING_PREP); try { startInternal(); } catch (LifecycleException e) { setState(LifecycleState.FAILED); throw e; } if (state.equals(LifecycleState.FAILED) || state.equals(LifecycleState.MUST_STOP)) { stop(); } else { // Shouldn't be necessary but acts as a check that sub-classes are // doing what they are supposed to. if (!state.equals(LifecycleState.STARTING)) { invalidTransition(Lifecycle.AFTER_START_EVENT); } setState(LifecycleState.STARTED); } }
@Override protected void startInternal() throws LifecycleException { fireLifecycleEvent(CONFIGURE_START_EVENT, null); setState(LifecycleState.STARTING); // Start our defined Services synchronized (services) { for (int i = 0; i < services.length; i++) { services[i].start(); } } }