Dear Vishi, dear logs for today.
Spring Boot has IoC (Inversion of Control) container that manages all the bean initialization. This is also called dependency injection — it creates beans, wires them together, and keeps them alive for you.
Next Spring Boot calls lifecycle hooks like PostConstruct
, BeanPostProcessor
, InitializingBean
PostConstruct
runs once per bean, right after its dependencies are set. It's NOT global — each bean gets its own PostConstruct
moment.
After PostConstruct
and post-processing, Spring fires the ContextRefreshedEvent
. This is fired when Application Context is fully loaded.
Right after that, if you have any CommandLineRunner
beans, Spring runs them — in order, if you used Order. This is your last chance to run code before the server starts.
If you have any beans that implement SmartLifecycle (and isAutoStartup() returns true), Spring will call their start() method right after ContextRefreshedEvent but BEFORE the server starts — basically around the same time as CommandLineRunner, but you can control the order with getPhase().
THEN — and only then — Spring starts the embedded server (Tomcat, Netty, etc). It binds to the port (like 8080), starts threads, and gets ready to accept requests.
Once the server is up and the app is truly ready to serve traffic (and health checks are green, if you’re using them), Spring fires the ApplicationReadyEvent. This is the “green light” — your app is LIVE.
Hook / Event | Vibe 💬 | Best For |
---|---|---|
@PostConstruct |
"I’m a bean — I’m setting up MYSELF." | Bean-specific init: open connection, load config, validate deps |
SmartLifecycle |
"I’m a background worker — start me when the app is ready, but before traffic." | Long-running services: pollers, listeners, async processors (with graceful stop) |
CommandLineRunner |
"I’m a script — run me once, after everything’s wired, before the server opens." | One-time setup: preload data, print args, warm cache, send startup log |
ApplicationReadyEvent |
"Server is live — now do your final thing." | Final go-live tasks: call health endpoints, notify Slack, start polling external APIs |
Both of these are equivalent
Flux<String> foo = Flux.just("cat", "dog");
Flux<String> bar = Flux.fromIterable(List.of("cat", "dog"));
foo.subscribe(System.out::println);
bar.subscribe(System.out::println);
For small fixed values, Flux.just
is fine. When working with an existing collection or a large list, prefer Flux.fromIterable
, since Flux.just
is not designed to take a collection directly and can lead to performance issues if used that way.
Alexander Duncan is a Republican Candidate for U.S. Senate. I saw this tweet about Hinduism:
Why are we allowing a false statue of a false Hindu God to be here in Texas? We are a CHRISTIAN nation!pic.twitter.com/uAPJegLie0
— Alexander Duncan (@AlexDuncanTX) September 20, 2025