Comprehensive Guide to Spring Boot Startup Sequence and Extension Points
This article provides an in‑depth explanation of the Spring Boot startup process, enumerates the key extension points, demonstrates their execution order with sample code and logs, and offers practical recommendations for correctly initializing RPC, MQ, and HTTP traffic.
Although most Java developers spend their time on CRUD operations, understanding the Spring framework and its integration with common middleware is essential for diagnosing startup‑related issues.
Overview of Spring Startup Order
A long diagram (not shown) illustrates the complete Spring bootstrapping flow, highlighting where RPC, HTTP, and MQ traffic should be opened.
Key Questions About Spring Startup
When does a RPC framework register services within Spring?
When does an MQ consumer start consuming messages?
When does the embedded Tomcat begin listening for HTTP requests?
Two recent production incidents were caused by Kafka consumers starting before Spring finished initializing, leading to missing event listeners and runtime errors.
Critical Extension Points
BeanFactoryAware – obtain BeanFactory
ApplicationContextAware – obtain ApplicationContext
BeanNameAware – obtain bean name
ApplicationListener – listen for ContextRefreshedEvent, etc.
CommandLineRunner – execute after the entire context is ready
SmartLifecycle#start – invoked after all singleton beans are initialized
@PostConstruct – bean initialization hook
InitializingBean – afterPropertiesSet method
init‑method – custom init method declared in XML or @Bean
BeanPostProcessor – pre‑ and post‑initialization processing
BeanFactoryPostProcessor – modify bean definitions before instantiation
Code Experiment to Verify Execution Order
The following class implements several Spring lifecycle interfaces and logs each callback:
public class TestSpringOrder implements ApplicationContextAware,
BeanFactoryAware,
InitializingBean,
SmartLifecycle,
BeanNameAware,
ApplicationListener
,
CommandLineRunner,
SmartInitializingSingleton {
// ... implementation omitted for brevity
}Additional methods are annotated with @PostConstruct and an initMethod is defined in XML:
@PostConstruct
public void postConstruct() {
log.error("启动顺序:post-construct");
}
public void initMethod() {
log.error("启动顺序:init-method");
}A second bean implements BeanPostProcessor and BeanFactoryPostProcessor to log before/after initialization:
public class TestSpringOrder3 implements BeanPostProcessor, BeanFactoryPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
log.error("启动顺序:BeanPostProcessor postProcessBeforeInitialization beanName:{}", beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
log.error("启动顺序:BeanPostProcessor postProcessAfterInitialization beanName:{}", beanName);
return bean;
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
log.error("启动顺序:BeanFactoryPostProcessor postProcessBeanFactory");
}
}Running the application produces the following log, which confirms the exact order of each lifecycle callback:
2023-11-25 18:10:53,748 [main] ERROR (TestSpringOrder3:37) - 启动顺序:BeanFactoryPostProcessor postProcessBeanFactory
2023-11-25 18:10:59,299 [main] ERROR (TestSpringOrder:53) - 启动顺序:构造函数 TestSpringOrder
2023-11-25 18:10:59,316 [main] ERROR (TestSpringOrder:127) - 启动顺序: Autowired
2023-11-25 18:10:59,316 [main] ERROR (TestSpringOrder:129) - 启动顺序:setBeanName
2023-11-25 18:10:59,316 [main] ERROR (TestSpringOrder:111) - 启动顺序:setBeanFactory
2023-11-25 18:10:59,316 [main] ERROR (TestSpringOrder:121) - 启动顺序:setApplicationContext
2023-11-25 18:10:59,316 [main] ERROR (TestSpringOrder3:25) - 启动顺序:BeanPostProcessor postProcessBeforeInitialization beanName:testSpringOrder
2023-11-25 18:10:59,316 [main] ERROR (TestSpringOrder:63) - 启动顺序:post-construct
2023-11-25 18:10:59,317 [main] ERROR (TestSpringOrder:116) - 启动顺序:afterPropertiesSet
2023-11-25 18:10:59,317 [main] ERROR (TestSpringOrder:46) - 启动顺序:init-method
2023-11-25 18:10:59,320 [main] ERROR (TestSpringOrder3:31) - 启动顺序:BeanPostProcessor postProcessAfterInitialization beanName:testSpringOrder
2023-11-25 18:17:21,563 [main] ERROR (SpringOrderConfiguartion:21) - 启动顺序: @Bean 注解方法执行
2023-11-25 18:17:21,668 [main] ERROR (TestSpringOrder:58) - 启动顺序:SmartInitializingSingleton
2023-11-25 18:17:21,675 [main] ERROR (TestSpringOrder:74) - 启动顺序:start
2023-11-25 18:17:23,508 [main] ERROR (TestSpringOrder:68) - 启动顺序:ContextRefreshedEvent
2023-11-25 18:17:23,574 [main] ERROR (TestSpringOrder:79) - 启动顺序:CommandLineRunnerPractical Recommendations
• Open HTTP, RPC, and MQ traffic only after SmartInitializingSingleton or the ContextRefreshedEvent has fired to ensure all Spring event listeners are registered.
• Do not start traffic in init‑method or @PostConstruct because the Spring context may still be incomplete.
• Use ApplicationListener or implement SmartLifecycle to perform post‑startup actions such as service registration (e.g., Eureka) or cache warm‑up.
Conclusion
Understanding the precise order of Spring’s extension points helps avoid subtle production bugs caused by premature traffic activation. By aligning RPC, MQ, and HTTP entry points with the appropriate lifecycle callbacks, developers can build more reliable Spring Boot applications.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
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.