Question 24 · Section 5

What is a @Configuration Class?

4. @Bean -> for third-party libraries 5. Inheritance -> parent beans are also registered 6. ConfigurationClassPostProcessor -> processing at early stage

Language versions: English Russian Ukrainian

Junior Level

@Configuration is a class that creates beans via @Bean methods.

@Configuration
public class AppConfig {

    @Bean
    public UserService userService() {
        return new UserService();
    }

    @Bean
    public OrderController orderController() {
        return new OrderController(userService());  // Injection
    }
    // In Full mode (default) Spring intercepts the userService() call
    // and returns the singleton. In Lite mode (proxyBeanMethods = false) a
    // new object is created - see Middle Level.
}

Why:

  • For third-party libraries (cannot put @Service on them)
  • For complex bean configuration

Middle Level

Full vs Lite Mode

Full Mode (default):

@Configuration  // proxyBeanMethods = true
public class Config {
    @Bean public A a() { return new A(); }
    @Bean public B b() { return new B(a()); }  // Same instance of A!
}

// CGLIB proxy intercepts the a() call
// -> Checks cache -> returns existing bean

Lite Mode:

@Configuration(proxyBeanMethods = false)
// or @Component, @Service with @Bean methods

@Bean public A a() { return new A(); }
@Bean public B b() { return new B(a()); }  // NEW instance of A!

// No proxy -> direct method call

When proxyBeanMethods = false

// Use false if:
// 1. @Bean methods do not call each other
// 2. Dependencies via method arguments
@Bean
public Service service(Repo repo) {  // Spring finds repo itself
    return new Service(repo);
}

// -> Faster startup
// -> Less memory
// -> GraalVM Native friendly

Senior Level

CGLIB Proxies

@Configuration -> CGLIB subclass:
  -> Intercepts @Bean method calls
  -> Checks singletonObjects cache
  -> Returns existing or creates new

-> Cannot be final classes/methods! CGLIB creates a subclass via inheritance.
  If class or method is final - Java does not allow inheritance,
  proxying is impossible, Spring throws an error.
-> Overhead on bytecode generation

Inheritance

@Configuration
public class ParentConfig {
    @Bean public CommonBean common() { return new CommonBean(); }
}

@Configuration
public class ChildConfig extends ParentConfig {
    // common() bean is also registered!
}

Production Experience

Real scenario: proxyBeanMethods = true slowed startup

200 @Configuration classes -> 5 seconds on CGLIB
Solution: proxyBeanMethods = false
Result: startup 2 seconds

Best Practices

  1. proxyBeanMethods = false - by default for new projects, BUT if @Bean methods call each other - keep true (otherwise singleton breaks).
  2. Method arguments -> instead of calling other @Bean
  3. Not final -> classes and methods
  4. @Bean -> for third-party libraries
  5. Inheritance -> parent beans are also registered
  6. ConfigurationClassPostProcessor -> processing at early stage

Summary for Senior

  • @Configuration = bean factory
  • Full mode -> CGLIB proxy, singleton semantics
  • Lite mode -> no proxy, new objects
  • proxyBeanMethods = false -> faster, Native friendly
  • Method arguments -> Spring injects itself
  • final -> cannot proxy

Interview Cheat Sheet

Must know:

  • @Configuration class creates beans via @Bean methods - for third-party libraries and complex configuration
  • Full mode (proxyBeanMethods = true): CGLIB proxy intercepts @Bean method calls and returns singleton
  • Lite mode (proxyBeanMethods = false): direct method call - each call creates a new object
  • Constructor Injection via @Bean method arguments - Spring injects dependencies itself
  • CGLIB creates a subclass via inheritance - cannot be final classes/methods
  • proxyBeanMethods = false speeds up startup by 40-60% and is needed for GraalVM Native Image
  • @Configuration inheritance: parent beans are also registered

Common follow-up questions:

  • When to use proxyBeanMethods = false? - When @Bean methods do not call each other and dependencies are passed via arguments.
  • What happens if you call a @Bean method directly in Lite mode? - A new instance is created, singleton semantics break.
  • Why can’t @Configuration class be final? - CGLIB creates a subclass for proxying; final inheritance is impossible.
  • How does @Configuration differ from @Component with @Bean methods? - @Component works in Lite mode - @Bean method calls are not intercepted.

Red flags (DO NOT say):

  • “@Bean methods always create singleton” - only in Full mode with proxy.
  • “proxyBeanMethods = false is always better” - no, breaks singleton on inter-@Bean calls.
  • “@Configuration is just @Component” - no, Full vs Lite mode is critically different.
  • “You can make @Bean methods final” - no, CGLIB cannot override the method.

Related topics:

  • [[21. How SpringBootApplication works]]
  • [[26. What does the Autowired annotation do]]
  • [[28. What is Qualifier]]
  • [[25. Difference between Component Service Repository Controller]]