Foundation · Understand
Java Configuration (@Bean)
@Configuration and @Bean bring classes you do not own—SDK clients, clocks, mappers—under container lifecycle and injection control.
Primary source: Spring Framework 6.2 Reference: Java-based Container Configuration
Lesson 6 of 14
1d streakThe Architectural Question
You cannot annotate a class inside a third-party JAR with @Component; configuration classes are the sanctioned bridge into the container.
What this guide proves
- @Configuration
- @Bean
- Third-party Beans
Full @Configuration vs Lite Mode: The CGLIB proxy divide
In Spring, Java-based configuration operates in one of two modes: Full Configuration Mode or Lite Configuration Mode. This distinction represents one of the most critical, yet frequently misunderstood, runtime mechanics in the entire framework.
| Mode | Class Annotation | Proxy Mechanism | Inter-Bean @Bean Call Semantics |
|---|---|---|---|
| Full Mode | @Configuration (proxyBeanMethods = true, default) | CGLIB subclass proxy generated at runtime | Method calls intercepted: returns cached container singleton instance. |
| Lite Mode | @Configuration(proxyBeanMethods = false) or @Component | No proxy (ordinary Java class) | Method calls execute raw Java code: creates a NEW duplicate instance each call! |
In Full mode, Spring generates a CGLIB subclass of your @Configuration class at startup. When one @Bean method calls another @Bean method (e.g. dataSource()), CGLIB intercepts the call, checks the BeanFactory singleton registry, and returns the existing managed singleton if already created. In Lite mode, no proxy exists, so calling the method simply invokes raw Java construction, producing duplicate instances!
When to use @Bean vs @Component
While @Component is ideal for classes whose source code you own, @Bean factory methods are essential in three production scenarios:
- 01Third-Party Library Classes: Configuring objects from external libraries (such as Jackson ObjectMapper, HikariDataSource, or RedisTemplate) where you cannot add @Component to the source code.
- 02Conditional / Programmatic Assembly: When instantiation requires algorithmic branching, environment evaluation, or dynamic parameters (e.g. constructing an in-memory client for dev and an OAuth2 client for prod).
- 03Explicit Lifecycle Control: Declaring custom init and destroy methods via @Bean(initMethod = "start", destroyMethod = "close").
@Configuration(proxyBeanMethods = true)
public class InfrastructureConfig {
@Bean
public ObjectMapper objectMapper() {
return JsonMapper.builder()
.findAndAddModules()
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.build();
}
@Bean
public AuditClient auditClient(ObjectMapper mapper) { // Method parameter injection!
return new AuditClient(mapper);
}
}Break it deliberately: Multiple instances in Lite mode
When developers use proxyBeanMethods = false (often to improve startup time or ahead-of-time compilation) and directly invoke other @Bean methods, they unknowingly violate singleton guarantees, creating multiple connection pools or caches.
@Configuration(proxyBeanMethods = false) // Lite mode: CGLIB proxying is DISABLED!
public class DangerousLiteConfig {
@Bean
public ConnectionPool pool() {
return new ConnectionPool(); // Costly resource!
}
@Bean
public OrderService orderService() {
return new OrderService(pool()); // Calls pool() directly!
}
@Bean
public PaymentService paymentService() {
return new PaymentService(pool()); // Calls pool() directly!
}
}// Output from ApplicationContext inspection: OrderService pool hashcode: ConnectionPool@7f31245a PaymentService pool hashcode: ConnectionPool@2a1844b2 WARN: Two separate ConnectionPool instances created! Total database connections doubled!
The universal best practice
Check your understanding
Active Recall Checkpoint
What runtime mechanism allows Spring to intercept direct @Bean method calls in a @Configuration class to enforce singleton semantics?
Hint: Think about bytecode manipulation and dynamic subclassing.
Show answer & explanation
Spring generates a CGLIB subclass proxy of the @Configuration class when proxyBeanMethods = true. The proxy intercepts calls between @Bean methods, querying the container singleton registry before executing the method body.
Active Recall Checkpoint
Why should backend developers prefer declaring @Bean dependencies as method parameters rather than calling @Bean methods directly?
Hint: Consider portability between Full mode and Lite mode.
Show answer & explanation
Method parameter injection works identically in both Full and Lite (proxyBeanMethods = false) modes, ensuring that dependencies are always resolved from the container rather than invoking accidental duplicate constructors.
Synthesis & Production Verification
Production Acceptance Criteria
- Expose a third-party type as a @Bean
- Prove two injection points share one instance
- Explain what proxyBeanMethods = false changes about intra-class calls
Key Takeaway
@Configuration(proxyBeanMethods = true) uses CGLIB subclass proxying to intercept direct @Bean method calls, ensuring singleton semantics. Lite mode or parameter injection avoids CGLIB overhead while guaranteeing clean dependency wiring.
Architectural & Technical Review
Core Interview Questions
Q01What is the difference between Full @Configuration and Lite configuration mode in Spring?Show answer
Full mode (@Configuration with proxyBeanMethods = true) generates a runtime CGLIB subclass proxy that intercepts calls between @Bean methods to return the cached container singleton. Lite mode (@Component with @Bean or proxyBeanMethods = false) skips CGLIB proxying, executing raw Java method calls.
Q02Why should dependencies between @Bean methods always be declared as method parameters rather than calling @Bean methods directly?Show answer
Declaring dependencies as method parameters works uniformly in both Full and Lite modes. It avoids accidental duplicate instance creation when proxyBeanMethods = false and makes dependency relationships explicit to the container.
Q03What happens when an @Bean method directly invokes another @Bean method inside a class with proxyBeanMethods = false?Show answer
Because CGLIB proxying is disabled, the call executes as a normal Java method invocation on 'this', creating a new, unmanaged duplicate instance and violating singleton guarantees.
Production Pitfalls
Critical Anti-Patterns
- Pitfall: Calling @Bean methods directly when proxyBeanMethods is false — In Lite mode, calling @Bean methods directly executes raw Java constructors, duplicating heavy resources like connection pools or client sessions.
- Pitfall: Putting heavy business logic inside @Bean factory methods — Factory methods should configure and instantiate beans, not execute business workflows or database transactions during container startup.
Primary Documentation & Specifications
Lesson Primary References
Supplementary Module Resources