Clean β’ Professional
Spring Bootβs bean creation and dependency management relies heavily on the BeanDefinition Loading & Registration Engine. This engine is the core of the Spring container, responsible for discovering, registering, and preparing all beans before they are instantiated. Mastering it is essential for debugging, optimizing startup, and understanding Spring Boot internals.
A BeanDefinition in Spring is metadata about a bean, not the bean instance itself. It serves as a blueprint for how Spring should create and configure a bean.
A BeanDefinition contains:
@PostConstruct, afterPropertiesSet, destroy methods@Conditional, @ConditionalOnClass, @ConditionalOnMissingBean, etc.Think of a BeanDefinition as a pre-instantiation plan. Beans are instantiated only after their BeanDefinitions are fully loaded and registered.
Spring Boot separates bean metadata loading from bean instantiation. This allows the framework to evaluate conditions, manage dependencies, and integrate auto-configuration seamlessly.
Spring Boot scans the classpath for classes annotated with:
@Component@Service@Repository@Controller@ConfigurationHow it works:
ClassPathBeanDefinitionScanner inspects the classpath.BeanDefinition for each discovered class.Example:
@Component
publicclassMyService {
}
MyService is created.MyService instance is not yet instantiated.@Configuration classes define beans using @Bean methods.@Bean method produces a BeanDefinition.Example:
@Configuration
publicclassAppConfig {
@Bean
public DataSourcedataSource() {
returnnewHikariDataSource();
}
}
DataSource is registered.Spring Boot auto-configuration also contributes BeanDefinitions.
SpringFactoriesLoaderAutoConfigurationImportSelector@ConditionalOnClass, @ConditionalOnMissingBean, etc.) are evaluated before registration.Example:
@Bean
@ConditionalOnMissingBean(DataSource.class)
public DataSourcedefaultDataSource() {
returnnewHikariDataSource();
}
All loaded BeanDefinitions are stored in the BeanDefinitionRegistry, typically DefaultListableBeanFactory.
Responsibilities:
Before instantiation, BeanDefinitions can be modified via:
BeanFactoryPostProcessorConfigurationPropertiesBindingPostProcessorWhat happens here:
@ConfigurationPropertiesSpring Boot uses this phase to tweak auto-configured beans before instantiation, ensuring flexibility.
Conditional annotations on BeanDefinitions are evaluated before bean creation:
@ConditionalOnClass β only load if class exists@ConditionalOnMissingBean β back off if user-defined bean exists@ConditionalOnProperty β only load if property matchesSkipped beans are recorded in the ConditionEvaluationReport, aiding debugging.
After all BeanDefinitions are loaded and processed:
@Autowired, constructor injection)@PostConstruct, afterPropertiesSet) are invokedThis separation of metadata loading and instantiation enables flexible, conditional, and environment-aware bean management.
| Scope | Description |
|---|---|
| singleton | One instance per Spring context (default) |
| prototype | New instance each time requested |
| request | Web scope β one instance per HTTP request |
| session | Web scope β one instance per session |
| application | One per ServletContext |
| websocket | One per WebSocket session |
@Lazy beans are instantiated on first use.1. Component Scan β detect@Component,@Service,@Controller,@Repository
2. Configuration Parsing β process@Configurationand@Bean methods
3. Auto-Configuration β load candidate auto-config classes via SpringFactoriesLoader
4. Conditional Evaluation βfilter beansusing@Conditional annotations
5. Registration β register BeanDefinitionsin BeanDefinitionRegistry
6. Post-Processing β modifyoradd BeanDefinitions via BeanFactoryPostProcessor
7. Bean Instantiation βcreate bean instances, inject dependencies, invoke lifecycle callbacks
@Configuration, and auto-configuration all generate BeanDefinitions.BeanFactoryPostProcessors allow dynamic modifications.The BeanDefinition Loading & Registration Engine is the backbone of Spring Bootβs IoC container:
SpringFactoriesLoaderMastering this engine is essential for advanced Spring Boot development, debugging startup issues, and customizing auto-configuration behavior.