2

There are different ways in which a bean initializaiton/cleanup can be done. Also there are other event mechanisms. Along with all this why does spring have the concept of starting the context which I believe invokes the respective start and stop methods of beans.

To test this, I have a piece of code that looks like this -

public class Car implements InitializingBean, DisposableBean, SmartLifecycle {

     private Engine engine;

     private volatile boolean isRunning = false;


    @Override
    public void afterPropertiesSet() throws Exception {
        logger.debug("Car -- afterPropertiesSet");
    }

    @Override
    public void destroy() throws Exception {
        logger.debug("Car -- destroy");
    }

    @PostConstruct
    public void postConstruction() {
        logger.debug("Car -- postConstruct");
    }

    @PreDestroy
    public void preDestruction() {
        logger.debug("Car -- preDestroy");
    }


    @Override
    public void stop() {
        //Note that this stop notification is not guaranteed to come before destruction: On regular shutdown, 
        //Lifecycle beans will first receive a stop notification before the general destruction callbacks are being propagated; 
        //however, on hot refresh during a context's lifetime or on aborted refresh attempts, only destroy methods will be called.
        logger.debug("Car -- stop");
        isRunning = false;
    }

    @Override
    public boolean isRunning() {
        //Check whether this component is currently running.
        //In the case of a container, this will return true only if all components that apply are currently running.
        logger.debug("Car -- isRunning");
        return isRunning;
    }

    @Override
    public int getPhase() {
        //Return the phase value of this object.
        logger.debug("Car -- getPhase");
        return 10;
    }

    @Override
    public boolean isAutoStartup() {
        //Returns true if this Lifecycle component should get started automatically by the container 
        //A value of false indicates that the component is intended to be started through an explicit start() call instead, 
        //analogous to a automatic Lifecycle.
        logger.debug("Car -- isAutoStartup");
        return false;
    }

    @Override
    public void stop(Runnable callback) {
        logger.debug("Car -- stop -  async");
        isRunning = false;
         try {

           //Sleeping for 10 seconds so that all threads 
           //get enough time to do their cleanup  
           TimeUnit.SECONDS.sleep(10);
           logger.debug("Wait over");
           //Shudown complete. Regular shutdown will continue.
           callback.run();
       } catch (final InterruptedException e) {
           //Looks like we got exception while shutting down, 
           //log it or do something with it
       }
    }

    @Override
    public void start() {
        //Start this component.
        //Should not throw an exception if the component is already running.
        logger.debug("Car -- start");
        isRunning = true;
    }
}

First I return true value for isAutoStartUp then I try returning false. The image below is a comparison of the log files of the 2 runs. Difference of log files And irrespective of whether autostartup is true/false, the code runs fine.

John Eipe
  • 10,922
  • 24
  • 72
  • 114
  • *That* code may run fine, but some more complicated beans probably need to do something in these lifecycle callbacks and may not work properly if you try to use them before they have been started (and may leave behind leaked resources if they are removed without having had a chance to neatly shut down). – Thilo Aug 15 '17 at 07:08
  • So the question is what do we put in those methods - best practices on what goes where?? – John Eipe Aug 15 '17 at 08:44

1 Answers1

0

This is for when your beans are related to services. You may want to know when they have started successfully, and also have a correct shutdown procedure/ cleanup/ teardown on a routine application shutdown.

UserF40
  • 3,533
  • 2
  • 23
  • 34