SoFunction
Updated on 2025-04-13

Spring SmartLifecycle: How to accurately control the life cycle of a bean

1. Core role

SmartLifecycleYes used in Spring frameworkPrecise control of component life cycle phasesThe advanced interface mainly solves three types of problems:

  1. Orderly start and stop: Control the startup/close order of multiple components
  2. Stage processing: Divide the initialization/destruction operation into different stages
  3. Contextual Awareness: Get the application context state change event

2. Typical application scenarios

Scene Specific use Advantages
Connection pool management Preheating and elegant shutdown of database/Redis connection pool Avoid connection leakage
Thread pool control Initialization and task evacuation of asynchronous thread pool Prevent tasks from being lost
External service registration Service Registration Center's online notification and offline cancellation Ensure consistency of service status
Timed task scheduling Start and pause of distributed task scheduler Accurately control the task execution cycle
Hardware device control IoT device connection initialization and safe disconnection Ensure the safety of equipment operation

3. Detailed explanation of the core method

public interface SmartLifecycle extends Lifecycle {
    
    // Key Method 1: Start the component (auto-trigger)    void start();
    
    // Key Method 2: Stop the component (with asynchronous notification)    default void stop(Runnable callback) {
        stop();
        ();
    }
    
    // Key Method 3: Phase Control (the smaller the value, the higher the priority)    int getPhase();
    
    // Other methods    boolean isAutoStartup();
    boolean isRunning();
}

4. Practical code examples

Basic case:

@Component
public class DatabaseConnector implements SmartLifecycle {
    private volatile boolean running = false;
    private ConnectionPool pool;

    @Override
    public void start() {
        if (!running) {
             = initConnectionPool(); // Preheat the connection pool            running = true;
        }
    }

    @Override
    public void stop() {
        if (running) {
            (); // Safely release the connection            running = false;
        }
    }

    @Override
    public int getPhase() {
        return Integer.MIN_VALUE + 1000; // High priority components    }
}

Actively end the processing case of the current thread:

@Slf4j
@Configuration
public class SensitiveWordsConfiguration implements SmartLifecycle {

    /**
     * lifeRunning
     */
    private volatile boolean lifeRunning = false;
    
    /**
      * Update time interval
      */
    private static final long UPDATE_TIME_SECONDS = 10 * 60;
    
    /**
      * Whether to terminate the thread
      */
    private volatile boolean threadStop = false;
    /**
     * taskExecutor
     */
    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;
    /**
      * Current thread task
      */
    private Future<?> future;
    
    /**
      * Implement hot updates and automatically load after modifying the dictionary
      */
    private void startScheduledUpdate() {
        while (!threadStop && !().isInterrupted()) {
            try {
                ("SensitiveWordConfig#startScheduledUpdate start update...");
                
                //This is the business process                //...
                
                (UPDATE_TIME_SECONDS);
            } catch (InterruptedException e) {
                ("SensitiveWordConfig#startScheduledUpdate interrupted: {}", ());
                ().interrupt();
                break;
            }
        }
    }

    @Override
    public void start() {
        // Start the task thread for regular update         = (this::startScheduledUpdate);
        lifeRunning = true;
    }

    @Override
    public void stop() {
        threadStop = true;
        // Actively terminate the current thread (otherwise it will continue to sleep until the thread pool shutdownNow causes the stop time to be occupied)        (true);
        lifeRunning = false;
    }

    @Override
    public boolean isRunning() {
        return lifeRunning;
    }

}

It is important to pay special attention to: In this case, ThreadPoolTaskExecutor in the spring context is used, so the @PreDestroy annotation method cannot be used for recycling, because when spring closes the container, it will first shutdown the thread pool in the upper and lower question before all bean destroy methods will be executed.

V. Phase control strategy

passgetPhase()Return value controls execution order:

  • Startup order: Phase valueFrom small to adultimplement
  • Close order: Phase valueFrom large to smallimplement

6. The difference from ordinary Lifecycle

characteristic Lifecycle SmartLifecycle
Automatic start ❌ Need to be triggered manually ✅ Support automatic startup
Stop callback ❌ None ✅ With asynchronous completion notification
Execution sequence control ❌ Not supported ✅ Precise phase value control
Context refresh integration ❌ Limited support ✅ Deep integration context lifecycle

7. Things to note

  1. Exception handling:existstart()/stop()Exceptions must be caught to avoid blocking the global life cycle process
  2. Thread safety: Ensure thread safety of implementing class methods
  3. Performance impact: Avoid executing time-consuming operations in lifecycle methods (>1 second operation recommended asynchronous)
  4. Container compatible:and@PostConstruct/@PreDestroyPay attention to the execution order when using annotations. Execution order@PostConstruct > start() > stop() > @PreDestroy

By using SmartLifecycle rationally, it can be achievedService zero interrupt restartResources are recycled in orderAdvanced features such as this are essential skills for building enterprise-level Spring applications.

Summarize

The above is personal experience. I hope you can give you a reference and I hope you can support me more.