/** * 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. */ publicinterfaceSingleUse { } }
/** * May the public methods other than property getters/setters and lifecycle * methods be called for a component in this state? It returns * <code>true</code> for any component in any of the following states: * <ul> * <li>{@link #STARTING}</li> * <li>{@link #STARTED}</li> * <li>{@link #STOPPING_PREP}</li> * </ul> * * @return <code>true</code> if the component is available for use, * otherwise <code>false</code> */ publicbooleanisAvailable() { return available; }
public String getLifecycleEvent() { return lifecycleEvent; } }
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 Lifecycle are:
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 LifecycleException.
The LifecycleEvents fired during state changes are defined in the methods that trigger the changed. No LifecycleEvents are fired if the attempted transition is not valid. 好的项目就是会把这样的示意图画得很好,把状态流转都画得很明确,而不一定要什么好看的作图工具,用字符就可以 而在 LifecycleBase类中是把更细节的实现了, init方法就是先判断了状态
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
@Override publicfinalsynchronizedvoidinit()throws LifecycleException { if (!state.equals(LifecycleState.NEW)) { // 只有状态是 new 才可以执行初始化 init invalidTransition(Lifecycle.BEFORE_INIT_EVENT); }
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()); } }
// Make sure parseBodyMethodsSet has a default if (null == parseBodyMethodsSet) { setParseBodyMethods(getParseBodyMethods()); }
if (protocolHandler.isAprRequired() && !AprStatus.isInstanceCreated()) { thrownewLifecycleException(sm.getString("coyoteConnector.protocolHandlerNoAprListener", getProtocolHandlerClassName())); } if (protocolHandler.isAprRequired() && !AprStatus.isAprAvailable()) { thrownewLifecycleException(sm.getString("coyoteConnector.protocolHandlerNoAprLibrary", getProtocolHandlerClassName())); } if (AprStatus.isAprAvailable() && AprStatus.getUseOpenSSL() && protocolHandler instanceof AbstractHttp11JsseProtocol) { AbstractHttp11JsseProtocol<?> jsseProtocolHandler = (AbstractHttp11JsseProtocol<?>) protocolHandler; if (jsseProtocolHandler.isSSLEnabled() && jsseProtocolHandler.getSslImplementationName() == null) { // OpenSSL is compatible with the JSSE configuration, so use it if APR is available jsseProtocolHandler.setSslImplementationName(OpenSSLImplementation.class.getName()); } }
try { setStateInternal(LifecycleState.STARTING_PREP, null, false); 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(); } elseif (!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()); } }
// Start our defined Connectors second synchronized (connectorsLock) { for (Connector connector: connectors) { // If it has already failed, don't try and start it if (connector.getState() != LifecycleState.FAILED) { connector.start(); } } } }