Spring Boot is popular because of its auto-configuration magic, but real systems often need more control than what auto-configuration provides. That’s where @Configuration and @Bean come in.
This guide explains:
- What
@Configurationand@Beanreally do - How they differ from
@Component - Why they are essential for production-grade applications
- Common pitfalls and best practices
This article is written for beginners to architects who want to understand Spring Boot beyond tutorials.
Why Manual Bean Configuration Exists
Spring Boot auto-configures components for you, but:
- Some libraries are not auto-configured
- Some components need conditional creation
- Some beans require customization
- Some beans depend on environment conditions
In these cases, using @Configuration and @Bean is necessary.
What Does @Configuration Do?
@Configuration marks a class as a source of bean definitions.
Example:
@Configuration
public class AppConfig {
}
This class tells Spring:
- “Don’t treat this like a normal class”
- “Look for
@Beanmethods inside” - “Manage these beans explicitly”
Internally, Spring enhances this class with a proxy so that @Bean methods return bean instances from the Spring container.
What Does @Bean Do?
@Bean tells Spring:
“The object returned by this method should be managed as a bean.”
Example:
@Configuration
public class AppConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
Spring:
- Calls the method
- Registers the returned object as a bean
- Manages its complete lifecycle
This is critical when the class of the bean:
- Belongs to a third-party library
- Can’t be annotated with
@Component
@Configuration vs @Component
At first glance:
@Componentmarks a class as a bean@Configurationmarks a class containing bean definitions
But internally:
@Configurationclasses are CGLIB proxies@Beanmethods are intercepted to guarantee singleton semantics
If you annotate a class with @Component and define @Bean inside:
@Component
public class BadConfig {
@Bean
public SomeClient someClient() { ... }
}
Spring may not apply full configuration semantics, causing subtle bugs.
Always use @Configuration for manual bean definitions.
Why @Configuration Matters Internally
When Spring processes a class annotated with @Configuration:
- It creates a proxy subclass
- Bean methods are intercepted
- Spring ensures:
- Only one instance per bean method
- Dependencies are injected correctly
- Bean post-processors are applied
This guarding ensures consistent lifecycles even when methods call each other.
Manual Beans: Real Production Use Cases
1. External Clients
For third-party SDKs (e.g., API clients):
@Bean
public WebClient webClient(WebClient.Builder builder) {
return builder
.baseUrl("https://api.example.com")
.build();
}
2. Conditional Beans
Depending on profiles:
@Bean
@ConditionalOnProperty(name="feature.email.enabled", havingValue="true")
public EmailService emailService() {
return new SmtpEmailService();
}
This pattern is widely used in real production systems.
3. Custom Configured Beans
When you need:
- Custom timeouts
- Special interceptors
- Multiple instances with varying behavior
Auto-configuration won’t cut it — manual beans give you control.
Common Bean Naming and Qualifier Issues
The default bean name is the method name.
If you have:
@Bean
public DataSource dataSource() { ... }
The bean name will be "dataSource".
If you create multiple beans of the same type, you must use:
@Qualifier@Primary- Explicit names
Example:
@Bean(name="readOnlyDataSource")
public DataSource readOnlyDataSource() { ... }
When Not to Use @Configuration/@Bean
Avoid:
- Heavy business logic inside config classes
- Database calls during bean creation
- Beans that depend on runtime state
Configuration should define how beans are wired — not what the beans do.
How This Connects to Spring Boot Startup Flow
Manual bean definition happens during application startup:
- Environment setup
- Automatic configuration
- Custom configuration classes are processed
- Beans are instantiated
- Post-processors are applied
Understanding this helps diagnose issues like:
- BeanCreationException
- Duplicate beans
- Missing beans
For a deeper look at startup flow:
https://springbootfixes.com/how-spring-boot-application-starts-startup-flow-explained/
Related Spring Boot Guides
- Spring Boot Bean Lifecycle Simplified
https://springbootfixes.com/how-spring-boot-creates-beans-bean-lifecycle-simplified-for-production/ - Component vs Service vs Repository Explained
https://springbootfixes.com/component-vs-service-vs-repository-in-spring-boot-what-actually-changes/ - Spring Boot Configuration & Profiles
https://springbootfixes.com/spring-boot-configuration-and-profiles-explained-beginner-to-production-guide/
Common Questions
Why use @Configuration instead of @Component?
Only @Configuration classes get full Spring proxying behavior which ensures correct singleton semantics for beans defined via @Bean.
Can I mix auto-configuration with manual beans?
Absolutely — manual beans override or complement auto-configuration when needed.
What if two @Bean methods return the same type?
Use @Qualifier or @Primary to resolve ambiguity.
Final Summary
@Configurationis a special kind of component meant for defining beans@Beanmethods create and register specific beans- Manual bean configuration deepens control in complex systems
- It’s essential for third-party libraries and conditional beans
- Correct use avoids subtle bugs in production
This post is ready for indexing and will help engineers understand a core Spring Boot concept deeply.
