001/*
002 * Copyright 2002-2019 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.context;
018
019/**
020 * An extension of the {@link Lifecycle} interface for those objects that require
021 * to be started upon {@code ApplicationContext} refresh and/or shutdown in a
022 * particular order.
023 *
024 * <p>The {@link #isAutoStartup()} return value indicates whether this object should
025 * be started at the time of a context refresh. The callback-accepting
026 * {@link #stop(Runnable)} method is useful for objects that have an asynchronous
027 * shutdown process. Any implementation of this interface <i>must</i> invoke the
028 * callback's {@code run()} method upon shutdown completion to avoid unnecessary
029 * delays in the overall {@code ApplicationContext} shutdown.
030 *
031 * <p>This interface extends {@link Phased}, and the {@link #getPhase()} method's
032 * return value indicates the phase within which this {@code Lifecycle} component
033 * should be started and stopped. The startup process begins with the <i>lowest</i>
034 * phase value and ends with the <i>highest</i> phase value ({@code Integer.MIN_VALUE}
035 * is the lowest possible, and {@code Integer.MAX_VALUE} is the highest possible).
036 * The shutdown process will apply the reverse order. Any components with the
037 * same value will be arbitrarily ordered within the same phase.
038 *
039 * <p>Example: if component B depends on component A having already started,
040 * then component A should have a lower phase value than component B. During
041 * the shutdown process, component B would be stopped before component A.
042 *
043 * <p>Any explicit "depends-on" relationship will take precedence over the phase
044 * order such that the dependent bean always starts after its dependency and
045 * always stops before its dependency.
046 *
047 * <p>Any {@code Lifecycle} components within the context that do not also
048 * implement {@code SmartLifecycle} will be treated as if they have a phase
049 * value of {@code 0}. This allows a {@code SmartLifecycle} component to start
050 * before those {@code Lifecycle} components if the {@code SmartLifecycle}
051 * component has a negative phase value, or the {@code SmartLifecycle} component
052 * may start after those {@code Lifecycle} components if the {@code SmartLifecycle}
053 * component has a positive phase value.
054 *
055 * <p>Note that, due to the auto-startup support in {@code SmartLifecycle}, a
056 * {@code SmartLifecycle} bean instance will usually get initialized on startup
057 * of the application context in any case. As a consequence, the bean definition
058 * lazy-init flag has very limited actual effect on {@code SmartLifecycle} beans.
059 *
060 * @author Mark Fisher
061 * @author Juergen Hoeller
062 * @author Sam Brannen
063 * @since 3.0
064 * @see LifecycleProcessor
065 * @see ConfigurableApplicationContext
066 */
067public interface SmartLifecycle extends Lifecycle, Phased {
068
069        /**
070         * The default phase for {@code SmartLifecycle}: {@code Integer.MAX_VALUE}.
071         * <p>This is different from the common phase {@code 0} associated with regular
072         * {@link Lifecycle} implementations, putting the typically auto-started
073         * {@code SmartLifecycle} beans into a later startup phase and an earlier
074         * shutdown phase.
075         * @since 5.1
076         * @see #getPhase()
077         * @see org.springframework.context.support.DefaultLifecycleProcessor#getPhase(Lifecycle)
078         */
079        int DEFAULT_PHASE = Integer.MAX_VALUE;
080
081
082        /**
083         * Returns {@code true} if this {@code Lifecycle} component should get
084         * started automatically by the container at the time that the containing
085         * {@link ApplicationContext} gets refreshed.
086         * <p>A value of {@code false} indicates that the component is intended to
087         * be started through an explicit {@link #start()} call instead, analogous
088         * to a plain {@link Lifecycle} implementation.
089         * <p>The default implementation returns {@code true}.
090         * @see #start()
091         * @see #getPhase()
092         * @see LifecycleProcessor#onRefresh()
093         * @see ConfigurableApplicationContext#refresh()
094         */
095        default boolean isAutoStartup() {
096                return true;
097        }
098
099        /**
100         * Indicates that a Lifecycle component must stop if it is currently running.
101         * <p>The provided callback is used by the {@link LifecycleProcessor} to support
102         * an ordered, and potentially concurrent, shutdown of all components having a
103         * common shutdown order value. The callback <b>must</b> be executed after
104         * the {@code SmartLifecycle} component does indeed stop.
105         * <p>The {@link LifecycleProcessor} will call <i>only</i> this variant of the
106         * {@code stop} method; i.e. {@link Lifecycle#stop()} will not be called for
107         * {@code SmartLifecycle} implementations unless explicitly delegated to within
108         * the implementation of this method.
109         * <p>The default implementation delegates to {@link #stop()} and immediately
110         * triggers the given callback in the calling thread. Note that there is no
111         * synchronization between the two, so custom implementations may at least
112         * want to put the same steps within their common lifecycle monitor (if any).
113         * @see #stop()
114         * @see #getPhase()
115         */
116        default void stop(Runnable callback) {
117                stop();
118                callback.run();
119        }
120
121        /**
122         * Return the phase that this lifecycle object is supposed to run in.
123         * <p>The default implementation returns {@link #DEFAULT_PHASE} in order to
124         * let {@code stop()} callbacks execute after regular {@code Lifecycle}
125         * implementations.
126         * @see #isAutoStartup()
127         * @see #start()
128         * @see #stop(Runnable)
129         * @see org.springframework.context.support.DefaultLifecycleProcessor#getPhase(Lifecycle)
130         */
131        @Override
132        default int getPhase() {
133                return DEFAULT_PHASE;
134        }
135
136}