博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LifecycleMBeanBase
阅读量:7110 次
发布时间:2019-06-28

本文共 42439 字,大约阅读时间需要 141 分钟。

hot3.png

LifecycleMBeanBase被许多类继承,本文浅析之(由分析知——jmx是tomcat的基础)

LifecycleMBeanBase继承了LifecycleBase,实现了jmxEnabled,内部依赖org.apache.tomcat.util.modeler.Registry

分别用于生命周期的管理(start,init,stop,destroy),以及jmx——java拓展管理

153201_DFrx_1380557.png

1 生命周期

All Implemented Interfaces:

, , 

Direct Known Subclasses:

, , , , , , , , ,, , , , 

Lifecycle:

主要实现start stop init destroy方法,并留有startInternal,stopInternal等方法给子类实现

/** * Common interface for component life cycle methods.  Catalina components * may implement this interface (as well as the appropriate interface(s) for * the functionality they support) in order to provide a consistent mechanism * to start and stop the component. * 
* The valid state transitions for components that support {@link Lifecycle} * are: *
 *            start() *  ----------------------------- *  |                           | *  | init()                    | * NEW -»-- INITIALIZING        | * | |           |              |     ------------------«----------------------- * | |           |auto          |     |                                        | * | |          \|/    start() \|/   \|/     auto          auto         stop() | * | |      INITIALIZED --»-- STARTING_PREP --»- STARTING --»- STARTED --»---  | * | |         |                                                            |  | * | |destroy()|                                                            |  | * | --»-----«--    ------------------------«--------------------------------  ^ * |     |          |                                                          | * |     |         \|/          auto                 auto              start() | * |     |     STOPPING_PREP ----»---- STOPPING ------»----- STOPPED -----»----- * |    \|/                               ^                     |  ^ * |     |               stop()           |                     |  | * |     |       --------------------------                     |  | * |     |       |                                              |  | * |     |       |    destroy()                       destroy() |  | * |     |    FAILED ----»------ DESTROYING ---«-----------------  | * |     |                        ^     |                          | * |     |     destroy()          |     |auto                      | * |     --------»-----------------    \|/                         | * |                                 DESTROYED                     | * |                                                               | * |                            stop()                             | * ----»-----------------------------»------------------------------ * * Any state can transition to FAILED. * * Calling start() while a component is in states STARTING_PREP, STARTING or * STARTED has no effect. * * Calling start() while a component is in state NEW will cause init() to be * called immediately after the start() method is entered. * * Calling stop() while a component is in states STOPPING_PREP, STOPPING or * STOPPED has no effect. * * Calling stop() while a component is in state NEW transitions the component * to STOPPED. This is typically encountered when a component fails to start and * does not start all its sub-components. When the component is stopped, it will * try to stop all sub-components - even those it didn't start. * * Attempting any other transition will throw {@link LifecycleException}. * * 
* The {@link LifecycleEvent}s fired during state changes are defined in the * methods that trigger the changed. No {@link LifecycleEvent}s are fired if the * attempted transition is not valid. * * @author Craig R. McClanahan */public interface Lifecycle { // ----------------------------------------------------- Manifest Constants /** * The LifecycleEvent type for the "component before init" event. */ public static final String BEFORE_INIT_EVENT = "before_init"; /** * The LifecycleEvent type for the "component after init" event. */ public static final String AFTER_INIT_EVENT = "after_init"; /** * The LifecycleEvent type for the "component start" event. */ public static final String START_EVENT = "start"; /** * The LifecycleEvent type for the "component before start" event. */ public static final String BEFORE_START_EVENT = "before_start"; /** * The LifecycleEvent type for the "component after start" event. */ public static final String AFTER_START_EVENT = "after_start"; /** * The LifecycleEvent type for the "component stop" event. */ public static final String STOP_EVENT = "stop"; /** * The LifecycleEvent type for the "component before stop" event. */ public static final String BEFORE_STOP_EVENT = "before_stop"; /** * The LifecycleEvent type for the "component after stop" event. */ public static final String AFTER_STOP_EVENT = "after_stop"; /** * The LifecycleEvent type for the "component after destroy" event. */ public static final String AFTER_DESTROY_EVENT = "after_destroy"; /** * The LifecycleEvent type for the "component before destroy" event. */ public static final String BEFORE_DESTROY_EVENT = "before_destroy"; /** * The LifecycleEvent type for the "periodic" event. */ public static final String PERIODIC_EVENT = "periodic"; /** * The LifecycleEvent type for the "configure_start" event. Used by those * components that use a separate component to perform configuration and * need to signal when configuration should be performed - usually after * {@link #BEFORE_START_EVENT} and before {@link #START_EVENT}. */ public static final String CONFIGURE_START_EVENT = "configure_start"; /** * The LifecycleEvent type for the "configure_stop" event. Used by those * components that use a separate component to perform configuration and * need to signal when de-configuration should be performed - usually after * {@link #STOP_EVENT} and before {@link #AFTER_STOP_EVENT}. */ public static final String CONFIGURE_STOP_EVENT = "configure_stop"; // --------------------------------------------------------- Public Methods /** * Add a LifecycleEvent listener to this component. * * @param listener The listener to add */ public void addLifecycleListener(LifecycleListener listener); /** * Get the life cycle listeners associated with this life cycle. * * @return An array containing the life cycle listeners associated with this * life cycle. If this component has no listeners registered, a * zero-length array is returned. */ public LifecycleListener[] findLifecycleListeners(); /** * Remove a LifecycleEvent listener from this component. * * @param listener The listener to remove */ public void removeLifecycleListener(LifecycleListener listener); /** * Prepare the component for starting. This method should perform any * initialization required post object creation. The following * {@link LifecycleEvent}s will be fired in the following order: *
    *
  1. INIT_EVENT: On the successful completion of component * initialization.
  2. *
* * @exception LifecycleException if this component detects a fatal error * that prevents this component from being used */ public void init() throws LifecycleException; /** * Prepare for the beginning of active use of the public methods other than * property getters/setters and life cycle methods of this component. This * method should be called before any of the public methods other than * property getters/setters and life cycle methods of this component are * utilized. The following {@link LifecycleEvent}s will be fired in the * following order: *
    *
  1. BEFORE_START_EVENT: At the beginning of the method. It is as this * point the state transitions to * {@link LifecycleState#STARTING_PREP}.
  2. *
  3. START_EVENT: During the method once it is safe to call start() for * any child components. It is at this point that the * state transitions to {@link LifecycleState#STARTING} * and that the public methods other than property * getters/setters and life cycle methods may be * used.
  4. *
  5. AFTER_START_EVENT: At the end of the method, immediately before it * returns. It is at this point that the state * transitions to {@link LifecycleState#STARTED}. *
  6. *
* * @exception LifecycleException if this component detects a fatal error * that prevents this component from being used */ public void start() throws LifecycleException; /** * Gracefully terminate the active use of the public methods other than * property getters/setters and life cycle methods of this component. Once * the STOP_EVENT is fired, the public methods other than property * getters/setters and life cycle methods should not be used. The following * {@link LifecycleEvent}s will be fired in the following order: *
    *
  1. BEFORE_STOP_EVENT: At the beginning of the method. It is at this * point that the state transitions to * {@link LifecycleState#STOPPING_PREP}.
  2. *
  3. STOP_EVENT: During the method once it is safe to call stop() for * any child components. It is at this point that the * state transitions to {@link LifecycleState#STOPPING} * and that the public methods other than property * getters/setters and life cycle methods may no longer be * used.
  4. *
  5. AFTER_STOP_EVENT: At the end of the method, immediately before it * returns. It is at this point that the state * transitions to {@link LifecycleState#STOPPED}. *
  6. *
* * Note that if transitioning from {@link LifecycleState#FAILED} then the * three events above will be fired but the component will transition * directly from {@link LifecycleState#FAILED} to * {@link LifecycleState#STOPPING}, bypassing * {@link LifecycleState#STOPPING_PREP} * * @exception LifecycleException if this component detects a fatal error * that needs to be reported */ public void stop() throws LifecycleException; /** * Prepare to discard the object. The following {@link LifecycleEvent}s will * be fired in the following order: *
    *
  1. DESTROY_EVENT: On the successful completion of component * destruction.
  2. *
* * @exception LifecycleException if this component detects a fatal error * that prevents this component from being used */ public void destroy() throws LifecycleException; /** * Obtain the current state of the source component. * * @return The current state of the source component. */ public LifecycleState getState(); /** * Obtain a textual representation of the current component state. Useful * for JMX. The format of this string may vary between point releases and * should not be relied upon to determine component state. To determine * component state, use {@link #getState()}. * * @return The name of the current component state. */ public String getStateName(); /** * Marker interface used to indicate that the instance should only be used * once. Calling {@link #stop()} on an instance that supports this interface * will automatically call {@link #destroy()} after {@link #stop()} * completes. */ public interface SingleUse { }}

主要定义事件的转态,事件的注册、注销等

lifeCycleBase

/** * Base implementation of the {@link Lifecycle} interface that implements the * state transition rules for {@link Lifecycle#start()} and * {@link Lifecycle#stop()} */public abstract class LifecycleBase implements Lifecycle {    private static final Log log = LogFactory.getLog(LifecycleBase.class);    private static final StringManager sm = StringManager.getManager(LifecycleBase.class);    /**     * The list of registered LifecycleListeners for event notifications.     */    private final List
lifecycleListeners = new CopyOnWriteArrayList<>(); /** * The current state of the source component. */ private volatile LifecycleState state = LifecycleState.NEW; private boolean throwOnFailure = true; ......}

其中用到了LifecycleListener和LlifeCycleState

/** * Interface defining a listener for significant events (including "component * start" and "component stop" generated by a component that implements the * Lifecycle interface. The listener will be fired after the associated state * change has taken place. * * @author Craig R. McClanahan */public interface LifecycleListener {    /**     * Acknowledge the occurrence of the specified event.     *     * @param event LifecycleEvent that has occurred     */    public void lifecycleEvent(LifecycleEvent event);}/** * The list of valid states for components that implement {@link Lifecycle}. * See {@link Lifecycle} for the state transition diagram. */public enum LifecycleState {    NEW(false, null),    INITIALIZING(false, Lifecycle.BEFORE_INIT_EVENT),    INITIALIZED(false, Lifecycle.AFTER_INIT_EVENT),    STARTING_PREP(false, Lifecycle.BEFORE_START_EVENT),    STARTING(true, Lifecycle.START_EVENT),    STARTED(true, Lifecycle.AFTER_START_EVENT),    STOPPING_PREP(true, Lifecycle.BEFORE_STOP_EVENT),    STOPPING(false, Lifecycle.STOP_EVENT),    STOPPED(false, Lifecycle.AFTER_STOP_EVENT),    DESTROYING(false, Lifecycle.BEFORE_DESTROY_EVENT),    DESTROYED(false, Lifecycle.AFTER_DESTROY_EVENT),    FAILED(false, null);    private final boolean available;    private final String lifecycleEvent;    private LifecycleState(boolean available, String lifecycleEvent) {        this.available = available;        this.lifecycleEvent = lifecycleEvent;    }    /**     * May the public methods other than property getters/setters and lifecycle     * methods be called for a component in this state? It returns     * true for any component in any of the following states:     * 
    *
  • {@link #STARTING}
  • *
  • {@link #STARTED}
  • *
  • {@link #STOPPING_PREP}
  • *
* * @return true if the component is available for use, * otherwise false */ public boolean isAvailable() { return available; } public String getLifecycleEvent() { return lifecycleEvent; }}/** * General event for notifying listeners of significant changes on a component * that implements the Lifecycle interface. * * @author Craig R. McClanahan */public final class LifecycleEvent extends EventObject { private static final long serialVersionUID = 1L; /** * Construct a new LifecycleEvent with the specified parameters. * * @param lifecycle Component on which this event occurred * @param type Event type (required) * @param data Event data (if any) */ public LifecycleEvent(Lifecycle lifecycle, String type, Object data) { super(lifecycle); this.type = type; this.data = data; } /** * The event data associated with this event. */ private final Object data; /** * The event type this instance represents. */ private final String type; /** * @return the event data of this event. */ public Object getData() { return data; } /** * @return the Lifecycle on which this event occurred. */ public Lifecycle getLifecycle() { return (Lifecycle) getSource(); } /** * @return the event type of this event. */ public String getType() { return this.type; }}/** *

* The root class from which all event state objects shall be derived. *

* All Events are constructed with a reference to the object, the "source", * that is logically deemed to be the object upon which the Event in question * initially occurred upon. * * @since JDK1.1 */public class EventObject implements java.io.Serializable { private static final long serialVersionUID = 5516075349620653480L; /** * The object on which the Event initially occurred. */ protected transient Object source; /** * Constructs a prototypical Event. * * @param source The object on which the Event initially occurred. * @exception IllegalArgumentException if source is null. */ public EventObject(Object source) { if (source == null) throw new IllegalArgumentException("null source"); this.source = source; } /** * The object on which the Event initially occurred. * * @return The object on which the Event initially occurred. */ public Object getSource() { return source; } /** * Returns a String representation of this EventObject. * * @return A a String representation of this EventObject. */ public String toString() { return getClass().getName() + "[source=" + source + "]"; }}

注意LifecycleBase的lifecycleListeners是copyOnWriteList

@Overridepublic final synchronized void init() throws LifecycleException {    if (!state.equals(LifecycleState.NEW)) {        invalidTransition(Lifecycle.BEFORE_INIT_EVENT);    }    try {        setStateInternal(LifecycleState.INITIALIZING, null, false);        initInternal();        setStateInternal(LifecycleState.INITIALIZED, null, false);    } catch (Throwable t) {        handleSubClassException(t, "lifecycleBase.initFail", toString());    }}

init方法是个同步方法,如果state的状态不是new,会抛出LifecycleException异常

private void invalidTransition(String type) throws LifecycleException {    String msg = sm.getString("lifecycleBase.invalidTransition", type, toString(), state);    throw new LifecycleException(msg);}

init方法调用initInternal(),是个抽象方法,留给子类实现

init方法两次调用setStateInternal方法,这也是同步方法,由于执行init的调用者已经获得当前对象的锁,所以会调用这个方法,而不阻塞(主要作用是触发监听其事件的监听器)

private synchronized void setStateInternal(LifecycleState state, Object data, boolean check)        throws LifecycleException {    if (log.isDebugEnabled()) {        log.debug(sm.getString("lifecycleBase.setState", this, state));    }    if (check) {        // Must have been triggered by one of the abstract methods (assume        // code in this class is correct)        // null is never a valid state        if (state == null) {            invalidTransition("null");            // Unreachable code - here to stop eclipse complaining about            // a possible NPE further down the method            return;        }        // Any method can transition to failed        // startInternal() permits STARTING_PREP to STARTING        // stopInternal() permits STOPPING_PREP to STOPPING and FAILED to        // STOPPING        if (!(state == LifecycleState.FAILED ||                (this.state == LifecycleState.STARTING_PREP &&                        state == LifecycleState.STARTING) ||                (this.state == LifecycleState.STOPPING_PREP &&                        state == LifecycleState.STOPPING) ||                (this.state == LifecycleState.FAILED &&                        state == LifecycleState.STOPPING))) {            // No other transition permitted            invalidTransition(state.name());        }    }    this.state = state;    String lifecycleEvent = state.getLifecycleEvent();    if (lifecycleEvent != null) {        fireLifecycleEvent(lifecycleEvent, data);    }}

 

/** * 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) {    LifecycleEvent event = new LifecycleEvent(this, type, data);    for (LifecycleListener listener : lifecycleListeners) {        listener.lifecycleEvent(event);    }}

这种处理异常的方式值得学习

private void handleSubClassException(Throwable t, String key, Object... args) throws LifecycleException {    ExceptionUtils.handleThrowable(t);    setStateInternal(LifecycleState.FAILED, null, false);    String msg = sm.getString(key, args);    if (getThrowOnFailure()) {        if (!(t instanceof LifecycleException)) {            t = new LifecycleException(msg, t);        }        throw (LifecycleException) t;    } else {        log.error(msg, t);    }}

这是start方法

/** * {@inheritDoc} */@Overridepublic final synchronized void start() throws LifecycleException {    if (LifecycleState.STARTING_PREP.equals(state) || LifecycleState.STARTING.equals(state) ||            LifecycleState.STARTED.equals(state)) {        //如果正在启动中,则打印日志,return        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();//如果状态是new,执行初始化    } else if (state.equals(LifecycleState.FAILED)) {        stop();//如果状态是failed,执行stop    } else if (!state.equals(LifecycleState.INITIALIZED) &&            !state.equals(LifecycleState.STOPPED)) {//如果已经初始化,或停止,抛异常        invalidTransition(Lifecycle.BEFORE_START_EVENT);    }    try {        setStateInternal(LifecycleState.STARTING_PREP, null, false);//设置全局state        startInternal();        if (state.equals(LifecycleState.FAILED)) {            // This is a 'controlled' failure. The component put itself into the            // FAILED state so call stop() to complete the clean-up.            stop();        } else if (!state.equals(LifecycleState.STARTING)) {            // Shouldn't be necessary but acts as a check that sub-classes are            // doing what they are supposed to.            invalidTransition(Lifecycle.AFTER_START_EVENT);        } else {            setStateInternal(LifecycleState.STARTED, null, false);        }    } catch (Throwable t) {        // This is an 'uncontrolled' failure so put the component into the        // FAILED state and throw an exception.        handleSubClassException(t, "lifecycleBase.startFail", toString());    }}

该方法会根据state值决定调用init,stop方法,以下是stop方法

/** * {@inheritDoc} */@Overridepublic final synchronized void stop() throws LifecycleException {    if (LifecycleState.STOPPING_PREP.equals(state) || LifecycleState.STOPPING.equals(state) ||            LifecycleState.STOPPED.equals(state)) {//如果将、正在、已经stop        if (log.isDebugEnabled()) {            Exception e = new LifecycleException();            log.debug(sm.getString("lifecycleBase.alreadyStopped", toString()), e);        } else if (log.isInfoEnabled()) {            log.info(sm.getString("lifecycleBase.alreadyStopped", toString()));        }        return;    }    if (state.equals(LifecycleState.NEW)) {        state = LifecycleState.STOPPED;        return;    }    if (!state.equals(LifecycleState.STARTED) && !state.equals(LifecycleState.FAILED)) {        invalidTransition(Lifecycle.BEFORE_STOP_EVENT);    }    try {        if (state.equals(LifecycleState.FAILED)) {            // Don't transition to STOPPING_PREP as that would briefly mark the            // component as available but do ensure the BEFORE_STOP_EVENT is            // fired            fireLifecycleEvent(BEFORE_STOP_EVENT, null);        } else {            setStateInternal(LifecycleState.STOPPING_PREP, null, false);        }        stopInternal();        // Shouldn't be necessary but acts as a check that sub-classes are        // doing what they are supposed to.        if (!state.equals(LifecycleState.STOPPING) && !state.equals(LifecycleState.FAILED)) {            invalidTransition(Lifecycle.AFTER_STOP_EVENT);        }        setStateInternal(LifecycleState.STOPPED, null, false);    } catch (Throwable t) {        handleSubClassException(t, "lifecycleBase.stopFail", toString());    } finally {        if (this instanceof Lifecycle.SingleUse) {            // Complete stop process first            setStateInternal(LifecycleState.STOPPED, null, false);            destroy();        }    }}

如果其实现了Lifecycle.SingleUse接口,会调用destroy方法(有一点疑问,在destroy()方法里也会调用stop()方法,会有问题吗)

@Overridepublic final synchronized void destroy() throws LifecycleException {    if (LifecycleState.FAILED.equals(state)) {        try {            // Triggers clean-up            stop();        } catch (LifecycleException e) {            // Just log. Still want to destroy.            log.warn(sm.getString(                    "lifecycleBase.destroyStopFail", toString()), e);        }    }    if (LifecycleState.DESTROYING.equals(state) || LifecycleState.DESTROYED.equals(state)) {        if (log.isDebugEnabled()) {            Exception e = new LifecycleException();            log.debug(sm.getString("lifecycleBase.alreadyDestroyed", toString()), e);        } else if (log.isInfoEnabled() && !(this instanceof Lifecycle.SingleUse)) {            // Rather than have every component that might need to call            // destroy() check for SingleUse, don't log an info message if            // multiple calls are made to destroy()            log.info(sm.getString("lifecycleBase.alreadyDestroyed", toString()));        }        return;    }    if (!state.equals(LifecycleState.STOPPED) && !state.equals(LifecycleState.FAILED) &&            !state.equals(LifecycleState.NEW) && !state.equals(LifecycleState.INITIALIZED)) {        invalidTransition(Lifecycle.BEFORE_DESTROY_EVENT);    }//只有 停止ed,失败ed,初始化ed,new 可以destroy,pre ing不可以    try {        setStateInternal(LifecycleState.DESTROYING, null, false);        destroyInternal();        setStateInternal(LifecycleState.DESTROYED, null, false);    } catch (Throwable t) {        handleSubClassException(t, "lifecycleBase.destroyFail", toString());    }}

 

2 jmx

/** * This interface is implemented by components that will be registered with an * MBean server when they are created and unregistered when they are destroyed. * It is primarily intended to be implemented by components that implement * {@link Lifecycle} but is not exclusively for them. */public interface JmxEnabled extends MBeanRegistration {    /**     * @return the domain under which this component will be / has been     * registered.     */    String getDomain();    /**     * Specify the domain under which this component should be registered. Used     * with components that cannot (easily) navigate the component hierarchy to     * determine the correct domain to use.     *     * @param domain The name of the domain under which this component should be     *               registered     */    void setDomain(String domain);    /**     * @return the name under which this component has been registered with JMX.     */    ObjectName getObjectName();}/** * 

Can be implemented by an MBean in order to * carry out operations before and after being registered or unregistered from * the MBean Server. An MBean can also implement this interface in order * to get a reference to the MBean Server and/or its name within that * MBean Server.

* 用于在mbean的注册前后、注销前后做相关操作 * @since 1.5 */public interface MBeanRegistration { /** * Allows the MBean to perform any operations it needs before * being registered in the MBean Server. If the name of the MBean * is not specified, the MBean can provide a name for its * registration. If any exception is raised, the MBean will not be * registered in the MBean Server. * * @param server The MBean Server in which the MBean will be registered. * * @param name The object name of the MBean. This name is null if * the name parameter to one of the createMBean or * registerMBean methods in the {@link MBeanServer} * interface is null. In that case, this method must return a * non-null ObjectName for the new MBean. * * @return The name under which the MBean is to be registered. * This value must not be null. If the name * parameter is not null, it will usually but not necessarily be * the returned value. * * @exception java.lang.Exception This exception will be caught by * the MBean Server and re-thrown as an {@link * MBeanRegistrationException}. */ public ObjectName preRegister(MBeanServer server, ObjectName name) throws java.lang.Exception; /** * Allows the MBean to perform any operations needed after having been * registered in the MBean server or after the registration has failed. *

If the implementation of this method throws a {@link RuntimeException} * or an {@link Error}, the MBean Server will rethrow those inside * a {@link RuntimeMBeanException} or {@link RuntimeErrorException}, * respectively. However, throwing an exception in {@code postRegister} * will not change the state of the MBean: * if the MBean was already registered ({@code registrationDone} is * {@code true}), the MBean will remain registered.

*

This might be confusing for the code calling {@code createMBean()} * or {@code registerMBean()}, as such code might assume that MBean * registration has failed when such an exception is raised. * Therefore it is recommended that implementations of * {@code postRegister} do not throw Runtime Exceptions or Errors if it * can be avoided.

* @param registrationDone Indicates whether or not the MBean has * been successfully registered in the MBean server. The value * false means that the registration phase has failed. */ public void postRegister(Boolean registrationDone); /** * Allows the MBean to perform any operations it needs before * being unregistered by the MBean server. * * @exception java.lang.Exception This exception will be caught by * the MBean server and re-thrown as an {@link * MBeanRegistrationException}. */ public void preDeregister() throws java.lang.Exception ; /** * Allows the MBean to perform any operations needed after having been * unregistered in the MBean server. *

If the implementation of this method throws a {@link RuntimeException} * or an {@link Error}, the MBean Server will rethrow those inside * a {@link RuntimeMBeanException} or {@link RuntimeErrorException}, * respectively. However, throwing an exception in {@code postDeregister} * will not change the state of the MBean: * the MBean was already successfully deregistered and will remain so.

*

This might be confusing for the code calling * {@code unregisterMBean()}, as it might assume that MBean deregistration * has failed. Therefore it is recommended that implementations of * {@code postDeregister} do not throw Runtime Exceptions or Errors if it * can be avoided.

*/ public void postDeregister(); }

3 Registry

    注册表,用于创建、操作mbean,并简化其使用,其自身也是一个mbean。以下是其全局变量

/*   Issues:   - exceptions - too many "throws Exception"   - double check the interfaces   - start removing the use of the experimental methods in tomcat, then remove     the methods ( before 1.1 final )   - is the security enough to prevent Registry beeing used to avoid the permission    checks in the mbean server ?*//** * Registry for modeler MBeans. * * This is the main entry point into modeler. It provides methods to create * and manipulate model mbeans and simplify their use. * * This class is itself an mbean. * * IMPORTANT: public methods not marked with @since x.x are experimental or * internal. Should not be used. * * @author Craig R. McClanahan * @author Costin Manolache */public class Registry implements RegistryMBean, MBeanRegistration  {    /**     * The Log instance to which we will write our log messages.     */    private static final Log log = LogFactory.getLog(Registry.class);    // Support for the factory methods    /** Will be used to isolate different apps and enhance security.     *  隔离app并增强其安全性:key用来隔离,Registry.guard确保安全性     */    private static final HashMap
perLoaderRegistries = null; /** * The registry instance created by our factory method the first time * it is called.所有注册表实例对应一个默认注册表 */ private static Registry registry = null; // Per registy fields /** * The
MBeanServer instance that we will use to register * management beans. 所有注册表有自己的MBeanServer */ private MBeanServer server = null; /** * The set of ManagedBean instances for the beans this registry * knows about, keyed by name. */ private HashMap
descriptors = new HashMap<>(); /** List of managed beans, keyed by class name */ private HashMap
descriptorsByClass = new HashMap<>(); // map to avoid duplicated searching or loading descriptors private HashMap
searchedPaths = new HashMap<>(); private Object guard;//守护者,用于阻止不信任的组件 // Id - small ints to use array access. No reset on stop() // Used for notifications private final Hashtable
> idDomains = new Hashtable<>(); private final Hashtable
ids = new Hashtable<>();

    getRegistry 获取注册表,静态同步方法,线程安全 

/**     * Factory method to create (if necessary) and return our     * Registry instance.     *     * The current version uses a static - future versions could use     * the thread class loader.     *     * @param key Support for application isolation. If null, the context class     * loader will be used ( if setUseContextClassLoader is called ) or the     * default registry is returned. key用于app隔离     * @param guard Prevent access to the registry by untrusted components 用于阻止不信任的组件访问注册表     * @return the registry     * @since 1.1     */    public static synchronized Registry getRegistry(Object key, Object guard) {        Registry localRegistry;        if( perLoaderRegistries!=null ) {            if( key==null )                key=Thread.currentThread().getContextClassLoader();//获取当前线程的classLoader            if( key != null ) {                localRegistry = perLoaderRegistries.get(key);                if( localRegistry == null ) {                    localRegistry=new Registry();//                    localRegistry.key=key;                    localRegistry.guard=guard;                    perLoaderRegistries.put( key, localRegistry );                    return localRegistry;                }                if( localRegistry.guard != null &&                        localRegistry.guard != guard ) {//验证守护者                    return null; // XXX Should I throw a permission ex ?                }                return localRegistry;            }        }        // static        if (registry == null) {//registry是静态的(单例)            registry = new Registry();        }        if( registry.guard != null &&                registry.guard != guard ) {            return null;        }        return (registry);    }

    getMBeanServer 实例、同步方法  获取MBeanServer,可以看出,每个registry的MBeanServer是单例、延时加载的

/**     * Factory method to create (if necessary) and return our     * MBeanServer instance.     * @return the MBean server     */    public synchronized MBeanServer getMBeanServer() {        if (server == null) {            long t1 = System.currentTimeMillis();            if (MBeanServerFactory.findMBeanServer(null).size() > 0) {                server = MBeanServerFactory.findMBeanServer(null).get(0);                if (log.isDebugEnabled()) {                    log.debug("Using existing MBeanServer " + (System.currentTimeMillis() - t1));                }            } else {                server = ManagementFactory.getPlatformMBeanServer();                if (log.isDebugEnabled()) {                    log.debug("Creating MBeanServer" + (System.currentTimeMillis() - t1));                }            }        }        return server;    }

         下面方法根据给定的bean、objectName,动态生成DynamicMBean,并注册到MBeanServer

/**     * Register a component     * 注册组件(jmx)     * @param bean The bean     * @param oname The object name     * @param type The registry type     * @throws Exception Error registering component     */    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传null时,type=bean的类名                type=bean.getClass().getName();            }            ManagedBean managed = findManagedBean(null, 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;        }    }

4  LifecycleMBeanBase

    以下是全局变量,jmx部分可参考 

private static final Log log = LogFactory.getLog(LifecycleMBeanBase.class);//日志    private static final StringManager sm =        StringManager.getManager("org.apache.catalina.util");//日志信息    /* Cache components of the MBean registration. */    private String domain = null;//jmx domain    private ObjectName oname = null;// jmx objectName    protected MBeanServer mserver = null;//jmx MBeanServer

    这是initInternal方法,init方法/start方法会调用。作用是初始化MBeanServer,将当前对象转成MBean并注册到MBeanServer中。获取mserver的方法在上面,重点看register方法

/**     * Sub-classes wishing to perform additional initialization should override     * this method, ensuring that super.initInternal() is the first call in the     * overriding method.     * 子类复写本方法时,需将super.initInternal()放第一行。与jmx的注册初始化相关     */    @Override    protected void initInternal() throws LifecycleException {        // If oname is not null then registration has already happened via        // preRegister().        if (oname == null) {            mserver = Registry.getRegistry(null, null).getMBeanServer();            oname = register(this, getObjectNameKeyProperties());        }    }    /**     * Utility method to enable sub-classes to easily register additional     * components that don't implement {@link JmxEnabled} with an MBean server.     * 方便子类注册组件到MBean server而不用实现JmxEabled     * 
* Note: This method should only be used once {@link #initInternal()} has * been called and before {@link #destroyInternal()} has been called. * * @param obj The object the register 要注册的对象 * @param objectNameKeyProperties The key properties component of the objectName要用 * object name to use to register the * object * * @return The name used to register the object */ 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()); //根据给定的bean与ObjectName, 生成DynamicMBean, 并注册到MBeanServer 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; } /** * Obtain the domain under which this component will be / has been * registered. */ @Override public final String getDomain() { if (domain == null) { domain = getDomainInternal(); } if (domain == null) { domain = Globals.DEFAULT_MBEAN_DOMAIN; } return domain; } /** * Method implemented by sub-classes to identify the domain in which MBeans * should be registered. * * @return The name of the domain to use to register MBeans. */ protected abstract String getDomainInternal();

这是destroyInternal方法

/**     * 子类复写此方法时,在方法的最后 super.destroyInternal()     * Sub-classes wishing to perform additional clean-up should override this     * method, ensuring that super.destroyInternal() is the last call in the     * overriding method.     */    @Override    protected void destroyInternal() throws LifecycleException {        unregister(oname);    }    /**     * Utility method to enable sub-classes to easily unregister additional     * components that don't implement {@link JmxEnabled} with an MBean server.     * 
* Note: This method should only be used once {@link #initInternal()} has * been called and before {@link #destroyInternal()} has been called. * * @param on The name of the component to unregister */ protected final void unregister(ObjectName on) { // If null ObjectName, just return without complaint if (on == null) { return; } // If the MBeanServer is null, log a warning & return if (mserver == null) { log.warn(sm.getString("lifecycleMBeanBase.unregisterNoServer", on)); return; } try { mserver.unregisterMBean(on); } catch (MBeanRegistrationException e) { log.warn(sm.getString("lifecycleMBeanBase.unregisterFail", on), e); } catch (InstanceNotFoundException e) { log.warn(sm.getString("lifecycleMBeanBase.unregisterFail", on), e); } }

        这是MBeanRegistration接口方法的实现,可以指定MBeanServer,  objectName, (因为在初始化时,都会先判空)

/** * Allows the object to be registered with an alternative * {@link MBeanServer} and/or {@link ObjectName}. */@Overridepublic final ObjectName preRegister(MBeanServer server, ObjectName name)        throws Exception {    this.mserver = server;    this.oname = name;    this.domain = name.getDomain();    return oname;}

 

 

转载于:https://my.oschina.net/u/1380557/blog/803978

你可能感兴趣的文章
深入Java虚拟机之虚拟机体系结构
查看>>
Bitcoin的解决的一个核心问题是什么
查看>>
java NIO2(file io)
查看>>
【读书笔记】06 | 白话容器基础(二):隔离与限制
查看>>
Django 学习笔记(二)
查看>>
Linux系统的grep以及正则表达式浅析!
查看>>
Orange的扩展插件Widgets开发(七)-GUI Control
查看>>
用python实现银行转账功能
查看>>
python学习笔记---列表
查看>>
Decorator 装饰器小记
查看>>
Centos6.5搭建Wiki
查看>>
linux 清空文件内容的方法
查看>>
2018“硅谷技划”随笔(三):人工智能火热背后的真正温度
查看>>
综合技术 --ORM
查看>>
我的友情链接
查看>>
[C++]STL萃取学习
查看>>
httpClient学习
查看>>
函数指针和指针函数的区别
查看>>
贪吃蛇小游戏
查看>>
搭建Mycat实现读写分离
查看>>