Run method on Spring Boot startup

Upasana | November 21, 2020 | 3 min read | 15,465 views | spring-boot


Spring Boot provides different mechanisms to run a specific code at Application Startup: ApplicationReadyEvent, CommandLineRunner and ApplicationRunner
application startup
Run method at startup

Running code on app startup is helpful in many scenarios like initializing DB related stuff, triggering notification about container startup, indexing db entities etc.

There are multiple ways to achieve this in Spring Boot -

  1. Using @Postconstruct method in singleton bean.

  2. Using ApplicationEvent - ApplicationReadyEvent or ContextRefreshEvent.

  3. Using CommandLineRunner

  4. Using ApplicationRunner

1. @PostConstruct

The PostConstruct annotation is used on a method that needs to be executed after dependency injection is done to perform any initialization. The init() method will not be called until any autowiring is done for the bean service.

Monitor.java
@Component
public class Monitor {

    @Autowired
    private SomeService someService;

    @PostConstruct
    public void init(){
        // initialize your monitor here, instance of someService is already injected by this time.
    }
}

Be noted that this method must not have any parameters.

2. CommandLineRunner

CommandLineRunner can be used to run code at application startup, provided it should be contained within SpringApplication. So if you are running program from a war file hosted inside a servlet container (instead of spring boot embedded containers), there may be problems.

Using Bean style approach:

CommandLineRunner example
@SpringBootApplication
public class Application {
	private static final Logger log = LoggerFactory.getLogger(Application.class);

	public static void main(String[] args) {
		SpringApplication.run(Application.class);
	}

	@Bean
	public CommandLineRunner demo(CustomerRepository repository) {
		return (args) -> {
			// save a couple of customers
		};
	}
}

Instead of creating a Bean, we can define a component for CommandLineRunner:

CommandLineRunner example
@Component
public class CommandLineAppStartupRunner implements CommandLineRunner {
    private static final Logger logger = LoggerFactory.getLogger(CommandLineAppStartupRunner.class);

    @Override
    public void run(String...args) throws Exception {
        logger.info("Application started with command-line arguments: {} . \n To kill this application, press Ctrl + C.", Arrays.toString(args));
    }
}

The advantage of defining a component is that we can specify the Order in which multiple such components run.

3. ApplicationRunner

CommandLineRunner does not provide access to ApplicationArguments, if we need access to access to ApplicationArguments instead of raw string array, then we can use ApplicationRunner.

ApplicationRunner example
@Component
public class ApplicationRunnerBean implements ApplicationRunner {
	@Override
	public void run(ApplicationArguments arg0) throws Exception {
		System.out.println("ApplicationRunnerBean");
	}
}

4. ApplicationReadyEvent in Spring Boot

Spring framework publishes event for ApplicationReadyEvent, which gets fired when the application is ready to service requests.

ApplicationReadyEvent example
@EventListener(ApplicationReadyEvent.class)
public void doSomethingAfterStartup() {
    System.out.println("hello world, I have just started up");
}
Use a SmartInitializingSingleton bean in spring > 4.1

SmartInitializingSingleton Callback interface triggered at the end of the singleton pre-instantiation phase during BeanFactory bootstrap.

@Bean
public SmartInitializingSingleton importProcessor() {
    return () -> {
        doStuff();
    };

}

Order of execution for multiple startup beans

Multiple CommandLineRunner/ApplicationRunner beans can be made to execute in a certain order at app startup using @Order annotation.

The bean with lowest order value will have the highest priority and hence will run before beans with higher order value. Default order value is Integer.MAX_VALUE which has lowest PRECEDENCE, hence will run in the last.

In the below code, CmdAppStartupRunner1 will run first and then CmdAppStartupRunner2

Multiple Beans execution in a pre-defined order
@Order(1)
@Component
public class CmdAppStartupRunner1 implements CommandLineRunner {
    private static final Logger logger = LoggerFactory.getLogger(CmdAppStartupRunner1.class);

    @Override
    public void run(String... args) {
        logger.info("Application started with command-line arguments: {} . " +
                "\n To kill this application, press Ctrl + C.", Arrays.toString(args));
    }
}

@Order(2)
@Component
public class CmdAppStartupRunner2 implements CommandLineRunner {
    private static final Logger logger = LoggerFactory.getLogger(CmdAppStartupRunner2.class);

    @Override
    public void run(String... args) {
        logger.info("Application started with command-line arguments: {} . " +
                "\n To kill this application, press Ctrl + C.", Arrays.toString(args));
    }
}
Program output

CmdAppStartupRunner1 will be executed before CmdAppStartupRunner2.


Buy my ebook for complete question bank

Most of these questions has been answered in my eBook "Cracking the Core Java Interview" updated on June 2018, that you can buy from this link:

Buy from Shunya (DRM Free PDF download with updates)

Top articles in this category:
  1. Setting a Random Port in Spring Boot Application at startup
  2. Running Spring Boot app as a service in unix
  3. Custom banner in spring boot
  4. Spring Boot multipart file upload server
  5. Spring Boot 2.0 Reactive Web Performance Metrics
  6. Redis rate limiter in Spring Boot
  7. Sendgrid Dynamic Templates with Spring Boot

Recommended books for interview preparation:

Find more on this topic:
Buy interview books

Java & Microservices interview refresher for experienced developers.