Week 3 Day 5 — Spring Boot Application Startup: Runners, Events, Lazy Initialization, and Startup Debugging
Goal
Today I want to understand what happens when a Spring Boot application starts.
Main questions:
- What does
SpringApplication.run(...)do? - What happens during application startup?
- What is
CommandLineRunner? - What is
ApplicationRunner? - What is the difference between them?
- When should I use runners?
- What are Spring Boot application events?
- What is
ApplicationReadyEvent? - What is
ApplicationFailedEvent? - What is lazy initialization?
- How can I debug startup problems?
- What are common exam traps?
1. Quick Review from Week 3 Day 4
In Day 4, I learned:
- Actuator provides production-ready monitoring and management endpoints.
/actuator/healthshows application health./actuator/metricsshows runtime metrics./actuator/beansshows registered Spring beans./actuator/conditionsshows auto-configuration decisions./actuator/configpropsshows configuration properties.- Actuator endpoints must be exposed and secured carefully.
Memory sentence:
Actuator helps me observe a running Spring Boot application.
Today I learn what happens when the application starts.
2. The Main Method
A normal Spring Boot app starts here:
@SpringBootApplication
public class KlarsyncApplication {
public static void main(String[] args) {
SpringApplication.run(KlarsyncApplication.class, args);
}
}
The most important line is:
SpringApplication.run(KlarsyncApplication.class, args);
Simple meaning:
Start the Spring Boot application.
But internally, a lot happens.
3. What Does SpringApplication.run(...) Do?
Simplified answer:
SpringApplication.run(...)creates and refreshes the SpringApplicationContext.
During startup, Spring Boot:
1. Creates SpringApplication
2. Prepares the environment
3. Loads application properties
4. Determines application type
5. Creates ApplicationContext
6. Registers configuration classes
7. Applies auto-configuration
8. Scans components
9. Registers BeanDefinitions
10. Creates singleton beans
11. Injects dependencies
12. Runs lifecycle callbacks
13. Starts embedded web server if needed
14. Runs ApplicationRunner and CommandLineRunner beans
15. Publishes application ready event
Memory sentence:
SpringApplication.runcreates, configures, refreshes, and starts the application context.
4. Startup Mental Model
Think of startup like this:
Read configuration
↓
Create container
↓
Register bean recipes
↓
Create beans
↓
Inject dependencies
↓
Initialize beans
↓
Start web server
↓
Run startup runners
↓
Application ready
Shorter version:
config -> context -> beans -> server -> runners -> ready
5. ApplicationContext Refresh
A key part of startup is:
refresh the ApplicationContext
Refreshing the context means Spring:
loads bean definitions
creates bean factory
registers post-processors
creates singleton beans
injects dependencies
initializes beans
starts lifecycle components
If context refresh fails, the application fails to start.
Example failure reasons:
missing bean
ambiguous bean
invalid configuration property
database configuration error
circular dependency
port already in use
bean initialization exception
6. What Happens Before Beans Are Created?
Before Spring creates beans, it prepares the environment.
Environment includes:
application.yml
application.properties
profile-specific files
environment variables
command-line arguments
system properties
active profiles
This is why properties and profiles are available during bean creation.
Example:
spring:
profiles:
active: dev
or:
java -jar app.jar --spring.profiles.active=prod
Spring Boot reads these early.
7. What Happens When Beans Are Created?
Spring creates beans according to their BeanDefinition.
For singleton beans, by default:
Spring creates them during startup.
Example:
@Service
public class TaskService {
public TaskService(TaskRepository taskRepository) {
}
}
Spring must create:
TaskRepository
TaskService
and inject dependencies.
If dependency injection fails, startup fails.
8. Startup Failure Example: Missing Bean
Code:
@Service
public class TaskService {
public TaskService(TaskRepository taskRepository) {
}
}
But no TaskRepository bean exists.
Possible error:
Parameter 0 of constructor in TaskService required a bean of type TaskRepository that could not be found.
Meaning:
Spring could not create TaskService because its dependency is missing.
Startup stops.
9. Startup Failure Example: Port Already in Use
If another process already uses port 8080, startup may fail.
Example:
Web server failed to start. Port 8080 was already in use.
Fix options:
stop the other process
change server.port
use a different profile
configure random port in tests
Example:
server:
port: 8081
10. Startup Failure Example: Invalid Config
YAML:
app:
max-tasks: abc
Java:
@ConfigurationProperties(prefix = "app")
public record AppProperties(
int maxTasks
) {
}
Spring cannot convert "abc" to int.
Result:
Application fails to start.
This is good because invalid configuration is detected early.
11. Startup Failure Example: DataSource
Dependency:
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
No datasource config.
Possible error:
Failed to configure a DataSource
Why?
Spring Boot sees JPA/database classes and tries to configure a DataSource.
Fix:
configure datasource
add database driver
use embedded DB for tests
remove JPA starter
exclude DataSourceAutoConfiguration only if truly needed
12. CommandLineRunner
CommandLineRunner lets me run code after the application context has started.
Example:
@Component
public class StartupRunner implements CommandLineRunner {
@Override
public void run(String... args) {
System.out.println("Application started with args:");
System.out.println(Arrays.toString(args));
}
}
If I start:
java -jar app.jar one two three
Then args contains:
one
two
three
Simple definition:
CommandLineRunnerruns startup code and receives raw command-line arguments.
13. ApplicationRunner
ApplicationRunner is similar, but it receives parsed application arguments.
Example:
@Component
public class StartupApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) {
System.out.println("Option names: " + args.getOptionNames());
}
}
Start app:
java -jar app.jar --mode=import --limit=100 file1.csv
ApplicationArguments can distinguish:
option arguments: --mode=import, --limit=100
non-option arguments: file1.csv
Simple definition:
ApplicationRunnerruns startup code and receives structured application arguments.
14. CommandLineRunner vs ApplicationRunner
| Topic | CommandLineRunner | ApplicationRunner |
|---|---|---|
| Method | run(String... args) | run(ApplicationArguments args) |
| Args style | raw String array | parsed arguments |
| Good for | simple startup args | option/non-option args |
| Runs when | after context startup | after context startup |
Memory sentence:
CommandLineRunnergets raw args.ApplicationRunnergets parsed args.
15. When Do Runners Run?
Runners run after the application context has been created and refreshed.
Important startup order:
1. Beans are created
2. Dependencies are injected
3. Application context is refreshed
4. ApplicationRunner and CommandLineRunner run
5. ApplicationReadyEvent is published
So runners are useful when I need to run code after beans are ready.
16. What Are Runners Used For?
Good use cases:
seed demo data in dev
validate startup assumptions
run one-time import in CLI app
log startup information
warm up caches carefully
start a simple command-line job
Example dev data:
@Component
@Profile("dev")
public class DevDataRunner implements ApplicationRunner {
private final UserRepository userRepository;
public DevDataRunner(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public void run(ApplicationArguments args) {
userRepository.save(new User("demo@example.com"));
}
}
17. Be Careful with Runners
Bad use cases:
long-running jobs that block startup
heavy imports on every production restart
dangerous data modification without profile protection
external calls without timeout
business logic that should be triggered by users or jobs
Bad:
@Component
public class DangerousRunner implements CommandLineRunner {
@Override
public void run(String... args) {
deleteAllData();
}
}
Better:
protect with profile
protect with property condition
run explicitly
use migration tools
use scheduled job
use admin endpoint
Memory sentence:
Runners are powerful, but they run every startup.
18. Protecting Runners with Profiles
Example:
@Component
@Profile("dev")
public class DevSeedDataRunner implements CommandLineRunner {
@Override
public void run(String... args) {
System.out.println("Seeding dev data");
}
}
This runner only runs in the dev profile.
It does not run in production.
19. Protecting Runners with Properties
Example:
@Component
@ConditionalOnProperty(
name = "app.seed.enabled",
havingValue = "true"
)
public class SeedDataRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) {
System.out.println("Seeding data");
}
}
YAML:
app:
seed:
enabled: true
This is useful when startup behavior should be controlled by configuration.
20. Ordering Multiple Runners
If multiple runners exist, I can control order.
Option 1:
@Component
@Order(1)
public class FirstRunner implements CommandLineRunner {
@Override
public void run(String... args) {
System.out.println("First");
}
}
@Component
@Order(2)
public class SecondRunner implements CommandLineRunner {
@Override
public void run(String... args) {
System.out.println("Second");
}
}
Option 2:
@Component
public class FirstRunner implements CommandLineRunner, Ordered {
@Override
public int getOrder() {
return 1;
}
@Override
public void run(String... args) {
System.out.println("First");
}
}
Memory sentence:
Use
@OrderorOrderedto control runner order.
21. Exceptions in Runners
If a runner throws an exception, startup usually fails.
Example:
@Component
public class FailingRunner implements CommandLineRunner {
@Override
public void run(String... args) {
throw new IllegalStateException("Startup failed");
}
}
Result:
Application fails to start.
This can be good if the app must not run with invalid state.
But be careful with non-critical tasks.
22. Runners in Web Apps vs CLI Apps
In a web app:
Runners execute during startup.
Then the app continues running and handles HTTP requests.
In a CLI app:
Runners can perform the main job.
Then the app may exit if no non-daemon threads keep it alive.
Spring Boot can be used for:
REST APIs
workers
CLI tools
batch-like jobs
message consumers
scheduled services
Not only web apps.
23. Application Events
Spring Boot publishes events during startup.
Simple definition:
Application events are notifications published by Spring Boot during different phases of startup and shutdown.
Important events:
ApplicationStartingEvent
ApplicationEnvironmentPreparedEvent
ApplicationContextInitializedEvent
ApplicationPreparedEvent
ApplicationStartedEvent
ApplicationReadyEvent
ApplicationFailedEvent
For certification, the most useful are:
ApplicationReadyEvent
ApplicationFailedEvent
24. ApplicationReadyEvent
ApplicationReadyEvent is published when the application is ready.
Example:
@Component
public class ReadyListener {
@EventListener(ApplicationReadyEvent.class)
public void onReady() {
System.out.println("Application is ready");
}
}
Meaning:
The application has started and runners have been called.
Use it when you need logic after the app is fully ready.
Memory sentence:
ApplicationReadyEventmeans the app is ready to service requests.
25. ApplicationStartedEvent vs ApplicationReadyEvent
Important distinction:
ApplicationStartedEvent happens after the context is refreshed but before runners run.
ApplicationReadyEvent happens after runners have run and the application is ready.
Memory sentence:
Started is before runners. Ready is after runners.
26. ApplicationFailedEvent
ApplicationFailedEvent is published if application startup fails.
Example concept:
public class StartupFailureListener {
@EventListener(ApplicationFailedEvent.class)
public void onFailure(ApplicationFailedEvent event) {
System.out.println("Application failed: " + event.getException().getMessage());
}
}
Important:
If the application context failed before this bean was created, a normal @Component listener may not be available.
For very early events, listeners often need to be registered differently.
Exam-safe memory:
ApplicationFailedEventsignals that startup failed.
27. Listening to Events with @EventListener
For normal application events, use:
@EventListener
Example:
@Component
public class StartupEvents {
@EventListener(ApplicationReadyEvent.class)
public void afterReady() {
System.out.println("Ready");
}
}
This is simple and common.
28. Early Events Need Early Registration
Some events happen before the application context is fully created.
Example:
ApplicationStartingEvent
ApplicationEnvironmentPreparedEvent
A listener registered as a normal bean may not receive these early events because the bean does not exist yet.
For early events, listeners can be registered directly on SpringApplication.
Example concept:
public static void main(String[] args) {
SpringApplication app = new SpringApplication(KlarsyncApplication.class);
app.addListeners(event -> System.out.println(event.getClass().getSimpleName()));
app.run(args);
}
Exam trap:
Not all startup events can be listened to by normal Spring beans.
29. Lazy Initialization
By default, singleton beans are usually created eagerly during startup.
Lazy initialization means:
Create beans only when they are first needed.
Enable globally:
spring:
main:
lazy-initialization: true
Or for one bean:
@Component
@Lazy
public class HeavyService {
}
30. Why Use Lazy Initialization?
Possible benefits:
faster startup
less memory used at startup
avoid creating rarely used beans
useful in development or special apps
Example:
@Component
@Lazy
public class ReportExportService {
public ReportExportService() {
System.out.println("Heavy service created");
}
}
This bean is created only when first requested.
31. Risks of Lazy Initialization
Lazy initialization can hide problems until runtime.
Example:
@Component
@Lazy
public class BrokenService {
public BrokenService(MissingDependency missingDependency) {
}
}
If lazy, the app may start successfully.
But later, when BrokenService is first requested, it fails.
Risks:
missing bean discovered late
configuration error discovered late
first request slower
runtime failure instead of startup failure
harder debugging
Memory sentence:
Lazy initialization can make startup faster but can delay errors.
32. Lazy Initialization and @PostConstruct
For a lazy bean, @PostConstruct runs when the bean is actually created.
Example:
@Component
@Lazy
public class HeavyService {
@PostConstruct
public void init() {
System.out.println("HeavyService initialized");
}
}
If no one needs HeavyService at startup, init() does not run at startup.
It runs later when the bean is first used.
33. Startup Debugging Tools
Useful tools:
startup logs
--debug
debug=true
Actuator /actuator/conditions
Actuator /actuator/beans
Actuator /actuator/configprops
dependency tree
failure analysis
application events
Memory sentence:
Debug startup by checking logs, conditions, beans, config, and dependencies.
34. --debug
Run:
java -jar app.jar --debug
or:
debug: true
This prints more diagnostic information, including auto-configuration condition details.
Use when asking:
Why did this auto-configuration match?
Why did this bean not exist?
Why is Boot trying to configure a DataSource?
35. Failure Analysis
Spring Boot often provides helpful failure analysis.
Example:
APPLICATION FAILED TO START
Description:
Parameter 0 of constructor in TaskService required a bean of type TaskRepository that could not be found.
Action:
Consider defining a bean of type TaskRepository in your configuration.
Read:
Description
Reason
Action
Caused by
Do not only read the first line.
Memory sentence:
Spring Boot failure analysis often tells you what failed and how to fix it.
36. Common Startup Error: Missing Bean
Error:
No qualifying bean of type 'EmailSender' available
Checklist:
Is the class annotated?
Is it inside component scan?
Is the active profile correct?
Is a condition preventing creation?
Is the dependency optional?
Are there test slices involved?
Is the bean created by @Bean but config class not scanned?
37. Common Startup Error: Multiple Beans
Error:
required a single bean, but 2 were found
Fix options:
@Primary
@Qualifier
inject List<T>
inject Map<String,T>
use more specific type
remove duplicate bean
check profiles
38. Common Startup Error: Circular Dependency
Example:
@Service
public class AService {
public AService(BService bService) {}
}
@Service
public class BService {
public BService(AService aService) {}
}
Problem:
AService needs BService.
BService needs AService.
Best fix:
refactor responsibilities
extract common service
use events
redesign dependencies
Avoid using lazy or setter workarounds as the first solution.
39. Common Startup Error: Invalid Configuration Properties
Error:
Failed to bind properties under 'app.max-tasks' to int
Check:
YAML value type
property name
relaxed binding
@ConfigurationProperties registration
validation annotations
active profile
environment variable override
40. Common Startup Error: Port Already Used
Error:
Port 8080 was already in use
Fix:
server:
port: 8081
Or find process:
lsof -i :8080
Then stop it if appropriate.
41. Common Startup Error: JPA/DataSource
Error:
Failed to configure a DataSource
Check:
Is data-jpa starter needed?
Is database driver added?
Is spring.datasource.url configured?
Is active profile correct?
Is Testcontainers or H2 needed in tests?
Should this app exclude DataSourceAutoConfiguration?
42. Startup Performance
Things that can slow startup:
too many beans
heavy @PostConstruct methods
slow database connection
slow external service health checks
heavy runners
classpath scanning
large auto-configuration set
complex entity scanning
too much work at startup
Good practice:
Keep startup logic small.
Avoid slow external calls during startup.
Use profiles/properties for optional startup tasks.
Move heavy jobs out of startup.
43. Measuring Startup with Actuator
Spring Boot Actuator can expose startup information if configured with startup tracking.
Conceptually, startup information can help answer:
Which startup steps took time?
Which bean took long to initialize?
Where is startup slow?
For certification, focus on the concept:
Startup can be debugged through logs, failure analysis, Actuator, and condition reports.
44. Runners vs @PostConstruct
| Topic | @PostConstruct | Runner |
|---|---|---|
| Runs | during bean initialization | after context startup |
| Belongs to | one bean lifecycle | application startup logic |
| Good for | initializing one bean | running app-level startup code |
| Has app args | no | yes |
| Can use all beans | limited; bean still initializing | yes, context is ready |
Memory sentence:
@PostConstructinitializes a bean. Runners run application-level startup logic.
45. Runners vs ApplicationReadyEvent
| Topic | Runner | ApplicationReadyEvent |
|---|---|---|
| Runs | after context started | after runners complete |
| Use for | startup tasks | logic after app is fully ready |
| Can fail startup | yes | yes, if exception is thrown |
| Gets args | yes | event does not focus on args |
Memory sentence:
Runners run before ready.
ApplicationReadyEventcomes after runners.
46. Runners vs Migrations
Do not use runners as a replacement for database migration tools.
Bad idea:
@Component
public class SchemaRunner implements CommandLineRunner {
public void run(String... args) {
createTablesManually();
}
}
Better tools:
Flyway
Liquibase
Use runners for data seeding or app-level startup tasks, not schema migration.
47. Runners and Transactions
A runner can call transactional services.
Example:
@Component
@Profile("dev")
public class DevSeedRunner implements ApplicationRunner {
private final DevSeedService devSeedService;
public DevSeedRunner(DevSeedService devSeedService) {
this.devSeedService = devSeedService;
}
@Override
public void run(ApplicationArguments args) {
devSeedService.seed();
}
}
Service:
@Service
public class DevSeedService {
@Transactional
public void seed() {
// save demo data
}
}
This is better than putting @Transactional on a self-invoked method inside the runner.
Memory sentence:
Let the runner call another bean if proxy-based behavior is needed.
48. Application Availability
Spring Boot has availability states.
Important concepts:
liveness
readiness
Liveness
Is the app alive?
Readiness
Is the app ready to receive traffic?
During startup:
App is not ready until startup completes.
After ready:
App can accept traffic.
This matters in deployment platforms like Kubernetes.
49. Common Exam Traps
Trap 1
SpringApplication.run(...) does much more than call main.
It creates and refreshes the ApplicationContext.
Trap 2
CommandLineRunner gets raw String... args.
ApplicationRunner gets parsed ApplicationArguments.
Trap 3
Runners run after the application context has been created and refreshed.
Trap 4
ApplicationStartedEvent happens before runners.
ApplicationReadyEvent happens after runners.
Trap 5
Runners execute on every startup.
Protect dangerous runners with profiles or properties.
Trap 6
If a runner throws an exception, startup can fail.
Trap 7
Lazy initialization can make startup faster but delay errors until runtime.
Trap 8
Normal Spring bean listeners may not receive very early startup events because the beans do not exist yet.
Trap 9
@PostConstruct is for bean initialization.
Runners are for application-level startup logic.
Trap 10
Read Spring Boot failure analysis carefully. It often tells the cause and action.
50. Real Exam Question: SpringApplication.run
Question:
What does SpringApplication.run(...) do?
Answer:
It starts the Spring Boot application by creating and refreshing the ApplicationContext, loading configuration, applying auto-configuration, scanning components, creating beans, injecting dependencies, running lifecycle callbacks, starting the web server if needed, running startup runners, and publishing application events.
51. Real Exam Question: CommandLineRunner
Question:
What is CommandLineRunner?
Answer:
CommandLineRunner is a callback interface that runs code after the application context has been created and refreshed. It receives raw command-line arguments as String... args.
52. Real Exam Question: ApplicationRunner
Question:
What is ApplicationRunner?
Answer:
ApplicationRunner is a callback interface that runs code after the application context has been created and refreshed. It receives parsed application arguments through ApplicationArguments.
53. Real Exam Question: Runner Difference
Question:
What is the difference between CommandLineRunner and ApplicationRunner?
Answer:
CommandLineRunner receives raw command-line arguments as a string array. ApplicationRunner receives parsed arguments as an ApplicationArguments object.
54. Real Exam Question: Runner Order
Question:
How can I order multiple runners?
Answer:
Use @Order or implement the Ordered interface.
55. Real Exam Question: Runner Exception
Question:
What happens if a runner throws an exception?
Answer:
The application startup usually fails.
56. Real Exam Question: ApplicationReadyEvent
Question:
When is ApplicationReadyEvent published?
Answer:
It is published when the application is fully started and ready, after runners have been called.
57. Real Exam Question: ApplicationStartedEvent
Question:
What is the difference between ApplicationStartedEvent and ApplicationReadyEvent?
Answer:
ApplicationStartedEvent is published after the application context is refreshed but before runners run. ApplicationReadyEvent is published after runners have run and the application is ready.
58. Real Exam Question: Lazy Initialization
Question:
What is lazy initialization?
Answer:
Lazy initialization means beans are created only when they are first needed instead of being created eagerly at startup.
59. Real Exam Question: Lazy Risk
Question:
What is a risk of lazy initialization?
Answer:
It can delay errors until runtime. Missing dependencies or configuration problems may not appear at startup but only when the lazy bean is first used.
60. Real Exam Question: @PostConstruct vs Runner
Question:
What is the difference between @PostConstruct and a runner?
Answer:
@PostConstruct runs during the lifecycle of a specific bean after its dependencies are injected. A runner runs application-level startup code after the application context has been created and refreshed.
61. Interview Answer
Question:
What happens when a Spring Boot application starts?
Good answer:
When a Spring Boot application starts, SpringApplication.run prepares the environment, loads configuration, creates the ApplicationContext, applies auto-configuration, scans components, registers bean definitions, creates singleton beans, injects dependencies, runs lifecycle callbacks, starts the embedded web server if needed, runs ApplicationRunner and CommandLineRunner beans, and finally publishes ApplicationReadyEvent.
62. Interview Answer
Question:
What is the difference between
CommandLineRunnerandApplicationRunner?
Good answer:
Both run after the application context has started. CommandLineRunner receives raw command-line arguments as String... args, while ApplicationRunner receives an ApplicationArguments object that separates option arguments and non-option arguments. I use ApplicationRunner when I want structured access to command-line options.
63. Interview Answer
Question:
When would you use a runner?
Good answer:
I would use a runner for application-level startup logic, such as seeding demo data in a development profile, running a command-line import job, validating startup assumptions, or logging startup information. I would avoid heavy or dangerous production tasks in runners unless they are protected by profiles or properties, because runners execute on every startup.
64. Interview Answer
Question:
What is lazy initialization?
Good answer:
Lazy initialization means Spring creates beans only when they are first needed instead of eagerly during startup. It can improve startup time and reduce initial memory usage, but it can also delay errors until runtime. For example, a missing dependency in a lazy bean might not fail application startup but fail later when the bean is first requested.
65. Interview Answer
Question:
How do you debug startup problems?
Good answer:
I start by reading the failure analysis and the root cause in the logs. Then I check whether the error is a missing bean, multiple beans, invalid configuration property, profile issue, port conflict, or auto-configuration problem. I can run with --debug, use Actuator /actuator/conditions, /actuator/beans, and /actuator/configprops, and inspect the dependency tree if the issue is dependency-related.
66. Tiny Code Practice
Create a runner:
@Component
@Profile("dev")
public class DevStartupRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) {
System.out.println("Dev startup runner executed");
}
}
Questions:
- When does this run?
- In which profile does it run?
- Does it receive raw args or parsed args?
Answers:
- After the application context has been created and refreshed.
- Only in the
devprofile. - It receives parsed args through
ApplicationArguments.
67. Tiny Bug Practice 1
Problem:
@Component
public class SeedRunner implements CommandLineRunner {
@Override
public void run(String... args) {
seedProductionData();
}
}
Question:
What is dangerous?
Answer:
The runner executes on every startup in every profile. If it modifies production data, it can be dangerous. Protect it with @Profile("dev"), @ConditionalOnProperty, or move the logic to a safer explicit process.
68. Tiny Bug Practice 2
Problem:
spring:
main:
lazy-initialization: true
The application starts successfully, but the first request fails with a missing bean error.
Question:
Why?
Answer:
Lazy initialization delayed bean creation until the first request. The missing dependency was not discovered at startup because the broken bean was not created until it was needed.
69. Tiny Bug Practice 3
Problem:
@Component
public class EarlyListener {
@EventListener(ApplicationStartingEvent.class)
public void onStarting() {
System.out.println("Starting");
}
}
The method does not run.
Question:
Why?
Answer:
ApplicationStartingEvent is published very early, before the application context is created and before this component exists as a bean. Early event listeners must be registered directly on SpringApplication or through another early registration mechanism.
Practice Questions and Answers
Question 1
What does SpringApplication.run(...) do?
Answer:
SpringApplication.run(...) starts the Spring Boot application by creating and refreshing the ApplicationContext, loading configuration, applying auto-configuration, scanning components, creating beans, injecting dependencies, running lifecycle callbacks, starting the web server if needed, running startup runners, and publishing application events.
Question 2
What is the simplified startup flow?
Answer:
A simplified startup flow is: read configuration, create context, register bean definitions, create beans, inject dependencies, initialize beans, start web server if needed, run runners, and publish ready event.
Question 3
What is CommandLineRunner?
Answer:
CommandLineRunner is a callback interface that runs code after the application context has started. It receives raw command-line arguments as String... args.
Question 4
What is ApplicationRunner?
Answer:
ApplicationRunner is a callback interface that runs code after the application context has started. It receives parsed application arguments as an ApplicationArguments object.
Question 5
What is the difference between CommandLineRunner and ApplicationRunner?
Answer:
CommandLineRunner receives raw string arguments. ApplicationRunner receives structured ApplicationArguments.
Question 6
When do runners run?
Answer:
Runners run after the application context has been created and refreshed, and before ApplicationReadyEvent.
Question 7
How can I order multiple runners?
Answer:
Use @Order or implement Ordered.
Question 8
What happens if a runner throws an exception?
Answer:
If a runner throws an exception, application startup usually fails.
Question 9
When should I use a runner?
Answer:
Use a runner for application-level startup logic such as dev data seeding, startup validation, CLI jobs, or safe cache warmup.
Question 10
Why should dangerous runners be protected with profiles or properties?
Answer:
Because runners execute on every startup. Dangerous runners can modify data or block production startup if not protected.
Question 11
What is ApplicationReadyEvent?
Answer:
ApplicationReadyEvent is published when the application is fully started and ready, after runners have executed.
Question 12
What is ApplicationFailedEvent?
Answer:
ApplicationFailedEvent is published when application startup fails.
Question 13
What is the difference between ApplicationStartedEvent and ApplicationReadyEvent?
Answer:
ApplicationStartedEvent happens after the context is refreshed but before runners run. ApplicationReadyEvent happens after runners have run and the app is ready.
Question 14
Why may normal bean listeners not receive very early events?
Answer:
Very early events can happen before the application context is created, so normal Spring beans do not exist yet and cannot receive those events.
Question 15
What is lazy initialization?
Answer:
Lazy initialization means beans are created only when first needed instead of being created eagerly during startup.
Question 16
How can I enable lazy initialization globally?
Answer:
Use:
spring:
main:
lazy-initialization: true
Question 17
What is a risk of lazy initialization?
Answer:
Lazy initialization can delay errors until runtime because broken beans may not be created during startup.
Question 18
What is the difference between @PostConstruct and a runner?
Answer:
@PostConstruct is bean-level initialization after dependency injection. A runner is application-level startup logic after the context has started.
Question 19
What are common startup failure causes?
Answer:
Common causes include missing beans, multiple matching beans, invalid configuration, circular dependencies, port conflicts, DataSource configuration errors, profile mistakes, and bean initialization exceptions.
Question 20
How can I debug startup problems?
Answer:
Use startup logs, failure analysis, --debug, debug=true, Actuator /actuator/conditions, /actuator/beans, /actuator/configprops, and dependency tree tools.
Final Memory Sentences
SpringApplication.runstarts the Spring Boot application.- Startup means config, context, beans, server, runners, ready.
CommandLineRunnerreceives rawString... args.ApplicationRunnerreceives parsedApplicationArguments.- Runners run after context startup and before
ApplicationReadyEvent. - Use
@OrderorOrderedto order runners. - If a runner throws an exception, startup can fail.
- Protect dangerous runners with profiles or properties.
ApplicationStartedEventhappens before runners.ApplicationReadyEventhappens after runners.ApplicationFailedEventsignals startup failure.- Very early events may happen before normal Spring beans exist.
- Lazy initialization creates beans when first needed.
- Lazy initialization can improve startup but delay errors.
@PostConstructis bean-level initialization.- Runners are application-level startup logic.
- Debug startup with logs, failure analysis, conditions, beans, configprops, and dependency tree tools.