5 Essential Spring Boot Extension Points Explained
This article walks through the five core Spring Boot extension points—ApplicationContextInitializer, ApplicationListener, Runner, BeanFactoryPostProcessor, and BeanPostProcessor—showing how they are discovered via SPI, where they are invoked in the startup flow, and how to implement and register custom extensions.
Introduction
When a Spring Boot application starts, the static SpringApplication.run method creates a SpringApplication instance and calls its run method. The run method delegates to prepareContext(), which in turn calls applyInitializers(), listeners.starting(), callRunners(), and finally the refresh logic that triggers various post‑processing hooks.
1. ApplicationContextInitializer
The first extension point is ApplicationContextInitializer. Spring Boot registers seven built‑in initializers via spring.factories. To add a custom initializer, you create a class implementing the interface, add its fully‑qualified name to spring.factories, and Spring’s SPI mechanism will load it. During startup, applyInitializers() iterates over all initializers and invokes their initialize() method, which is why a breakpoint in a custom initializer shows the call stack originating from prepareContext().
2. ApplicationListener
Listeners are another SPI‑based extension point. They follow the observer pattern: ApplicationEventMulticaster publishes events, and any ApplicationListener receives them. By defining listeners for ApplicationStartingEvent and ApplicationStartedEvent (with generic type <ApplicationEvent>), adding them to spring.factories, and running the application, you can see the events being broadcast from SpringApplication.run() → listeners.starting() and later listeners.started().
3. Runner
After the started event, Spring Boot invokes callRunners(). It retrieves all beans implementing ApplicationRunner or CommandLineRunner from the container and executes them in a loop. This is useful for tasks that should run after the context is fully initialized, such as registering the service with a discovery server or cleaning up resources.
4. BeanFactoryPostProcessor
Within refreshContext(), Spring calls invokeBeanFactoryPostProcessors(). Any BeanFactoryPostProcessor registered (again via spring.factories) can modify BeanDefinition objects before the beans are instantiated. The article demonstrates creating a custom processor that changes bean definition properties and shows the printed output confirming its execution.
5. BeanPostProcessor
After bean instances are created via reflection, Spring registers BeanPostProcessor implementations through registerBeanPostProcessors(). These processors provide two callbacks: postProcessBeforeInitialization and postProcessAfterInitialization. The common practice is to use the latter, which is how Spring’s AOP infrastructure works. The author creates a simple BeanPostProcessor, runs the application, and observes the callback being invoked from finishBeanFactoryInitialization().
Conclusion
The article assembles a complete diagram of when each extension point is triggered during the Spring Boot startup sequence, helping developers decide which hook to implement for a given use case. It also notes that many additional Spring extension points (e.g., InitializeBean, Aware) exist beyond the five covered.
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.
IT Niuke
Focused on IT technology sharing, original and innovative content. IT Niuke, we grow together.
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.
