Run method on application startup in Spring Boot

Carvia Tech | May 23, 2019 | 3 min read | 551 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

Using @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.

Using 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
		};
	}
}

Using a component approach, code might look different:

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));
    }
}

Using 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");
	}
}

Using ApplicationEvent 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 2.0 Reactive Web Performance Metrics
  5. Prevent Lost Updates in Database Transaction using Spring Hibernate
  6. How will you test web layer in Spring Boot using WebMvcTest annotation?
  7. What is new in Spring Boot 2



Find more on this topic:
Spring Framework image
Spring Framework

Spring Framework - MVC, Dependency Injection, Spring Hibernate, Spring Data JPA, Spring Boot and Spring Cloud for Microservices Architecture.

Last updated 1 week ago


Recommended books for interview preparation:

This website uses cookies to ensure you get the best experience on our website. more info