How to Run Custom Code at Spring Boot Startup: 8 Implementation Options
This article explains eight ways to execute custom initialization logic during Spring Boot startup, covering CommandLineRunner, ApplicationRunner, ApplicationListener, @EventListener, @PostConstruct, BeanPostProcessor, InitializingBean, SmartInitializingSingleton, and the main method, with code examples and suitable use‑case guidance.
Spring Boot startup initialization mechanisms
CommandLineRunner and ApplicationRunner
Both interfaces are invoked after the application has started. CommandLineRunner receives the raw String[] args and is suitable for simple argument handling. ApplicationRunner receives an ApplicationArguments object, which simplifies parsing complex arguments.
Example:
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@Component
public class MyCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("Executing CommandLineRunner logic!");
for (String arg : args) {
System.out.println("Startup argument: " + arg);
}
}
}Example:
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
@Component
public class MyApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("Executing ApplicationRunner logic!");
if (args.containsOption("debug")) {
System.out.println("Debug mode enabled!");
}
}
}Typical use: execute logic immediately after the application starts, such as loading caches or registering services.
ApplicationListener for startup events
Implement ApplicationListener<ApplicationReadyEvent> to run code when the application is fully ready.
Example:
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
System.out.println("Application is ready – executing ApplicationReadyEvent logic!");
}
}Typical use: perform actions after the application has completely started, such as registering with a monitoring system.
@EventListener annotation
The @EventListener annotation provides a concise way to listen for events without implementing the listener interface.
Example:
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class MyEventListener {
@EventListener(ApplicationStartedEvent.class)
public void onApplicationStarted() {
System.out.println("ApplicationStartedEvent triggered – custom logic executed!");
}
}Typical use: listen to specific events such as application start or shutdown.
@PostConstruct annotation
The standard Java @PostConstruct annotation runs after a bean’s dependencies have been injected and the bean is fully initialized.
Example:
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
@Service
public class MyService {
@PostConstruct
public void init() {
System.out.println("@PostConstruct executed after bean initialization!");
}
}Typical use: execute logic once a particular bean is ready, such as establishing a database connection.
BeanPostProcessor
Implementing BeanPostProcessor allows insertion of logic before and after any bean’s initialization.
Example:
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("Before initializing bean: " + beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("After initializing bean: " + beanName);
return bean;
}
}Typical use: enhance or modify bean initialization globally.
InitializingBean interface
Implementing InitializingBean requires overriding afterPropertiesSet(), which runs after all bean properties have been set.
Example:
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
@Component
public class MyInitializingBean implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Properties set – afterPropertiesSet() executed!");
}
}Typical use: run logic after property injection is complete.
SmartInitializingSingleton interface
This interface’s afterSingletonsInstantiated() method is called once all singleton beans have been created.
Example:
import org.springframework.context.SmartInitializingSingleton;
import org.springframework.stereotype.Component;
@Component
public class MySmartInitializingSingleton implements SmartInitializingSingleton {
@Override
public void afterSingletonsInstantiated() {
System.out.println("All singleton beans initialized – executing afterSingletonsInstantiated()!");
}
}Typical use: ensure that logic runs only after the entire application context is fully prepared.
Executing logic in the main method
The main method can contain custom code before and after the call to SpringApplication.run.
Example:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
System.out.println("Custom logic before Spring Boot startup!");
SpringApplication.run(MyApplication.class, args);
System.out.println("Custom logic after Spring Boot startup!");
}
}Typical use: execute global logic surrounding the entire startup process.
Choosing the appropriate mechanism
Select the mechanism based on when the code must run: immediately after startup ( CommandLineRunner / ApplicationRunner), on specific lifecycle events ( ApplicationListener / @EventListener), after a bean is ready ( @PostConstruct / InitializingBean), after all singleton beans are ready ( SmartInitializingSingleton), or globally around startup ( main method).
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Shepherd Advanced Notes
Dedicated to sharing advanced Java technical insights, daily work snippets, and the power of persistent effort.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
