@Configuration & @Bean
Beginner@Configuration marks a class as a source of bean definitions; @Bean methods create and configure objects that are managed by the Spring container.
Overview
@Configuration is a specialised @Component that tells Spring the class contains @Bean factory methods. Each @Bean method instantiates, configures, and returns an object that Spring registers in the ApplicationContext. Spring uses CGLIB to subclass @Configuration classes, so inter-bean method calls (e.g. calling dataSource() from entityManagerFactory()) return the same singleton bean instead of creating a new instance. This is the programmatic alternative to XML configuration and is the foundation for Spring Boot's auto-configuration.
@Configuration & @Bean Basics
@Bean methods can declare dependencies as parameters — Spring injects them by type. Bean name defaults to the method name; override with @Bean(name="..."). Scope defaults to singleton; use @Scope("prototype") for a new instance per injection.
@Configuration
public class DataSourceConfig {
// @Bean method — Spring calls this once and caches the result (singleton)
@Bean
public DataSource dataSource(DataSourceProperties props) {
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl(props.getUrl());
ds.setUsername(props.getUsername());
ds.setPassword(props.getPassword());
ds.setMaximumPoolSize(10);
return ds;
}
// Bean depending on another bean — Spring injects dataSource() singleton
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
// Custom bean name
@Bean(name = "primaryCache")
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager("products", "orders");
}
// Prototype scope — new instance per injection point
@Bean
@Scope("prototype")
public OrderProcessor orderProcessor() {
return new OrderProcessor();
}
}Conditional Beans
@ConditionalOnProperty, @ConditionalOnClass, and @ConditionalOnMissingBean allow beans to be registered only when certain conditions are met. This is how Spring Boot auto-configuration works.
@Configuration
public class CacheConfig {
// Register Redis cache only if spring.cache.type=redis
@Bean
@ConditionalOnProperty(name = "spring.cache.type", havingValue = "redis")
public CacheManager redisCacheManager(RedisConnectionFactory cf) {
return RedisCacheManager.create(cf);
}
// Fallback — in-memory cache if no custom CacheManager is defined
@Bean
@ConditionalOnMissingBean(CacheManager.class)
public CacheManager defaultCacheManager() {
return new ConcurrentMapCacheManager("products");
}
// Only register if Micrometer is on the classpath
@Bean
@ConditionalOnClass(MeterRegistry.class)
public CacheMetricsRegistrar cacheMetrics(MeterRegistry registry) {
return new CacheMetricsRegistrar(registry);
}
}@Configuration vs @Component for Bean Definitions
@Configuration uses CGLIB proxying so inter-@Bean calls return singletons. @Component (lite mode) does NOT proxy — inter-@Bean calls create new instances. Use @Configuration for proper singleton semantics.
// ✓ @Configuration — CGLIB proxy ensures singletons
@Configuration
public class AppConfig {
@Bean public A a() { return new A(b()); } // b() returns the singleton
@Bean public B b() { return new B(); }
@Bean public C c() { return new C(b()); } // same B instance as a()
}
// ✗ @Component (lite mode) — no proxy, b() creates a NEW instance each call
@Component
public class AppConfig {
@Bean public A a() { return new A(b()); } // new B created here
@Bean public B b() { return new B(); }
@Bean public C c() { return new C(b()); } // DIFFERENT B instance — bug!
}
// Rule: always use @Configuration when @Bean methods call each other
// Safe alternative — inject via parameter instead of method call:
@Configuration
public class AppConfig {
@Bean public A a(B b) { return new A(b); } // Spring injects singleton B
@Bean public B b() { return new B(); }
@Bean public C c(B b) { return new C(b); } // same B injected
}Key Points to Remember
- 1@Configuration classes are CGLIB-proxied — inter-@Bean method calls return the same singleton.
- 2@Bean methods are factory methods; Spring calls them once (singleton scope) by default.
- 3Bean name defaults to method name; override with @Bean(name="...").
- 4@ConditionalOnProperty, @ConditionalOnMissingBean etc. enable conditional bean creation.
- 5@Component in "lite mode" does NOT proxy — avoid calling @Bean methods from each other.
- 6Prefer injecting beans via @Bean method parameters over calling other @Bean methods.
Interview Questions
Sign in to ask AriaWhat is the difference between @Configuration and @Component for defining beans?
Why does Spring use CGLIB to proxy @Configuration classes?
How does @ConditionalOnMissingBean work?
What is the default scope of a @Bean and how do you change it?
What happens if two @Bean methods in different @Configuration classes have the same name?
Ask Aria about @Configuration & @Bean
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.