proxyBeanMethods = true vs false. When to set false? — Cracked Java
// Spring Framework & Spring Boot · IoC, Dependency Injection, ApplicationContext
SeniorTheoryTrick

proxyBeanMethods = true vs false. When to set false?

proxyBeanMethods is the attribute on @Configuration that switches the CGLIB proxy on or off. true (the default) gives "full mode" — inter-@Bean calls return the shared singleton. false gives "lite mode" — no proxy, faster startup, but a direct call to another @Bean method creates a new instance. You set it false when your configuration never calls one @Bean method from another.

What each setting does

@Configuration(proxyBeanMethods = false)   // lite mode
public class AppConfig {
    @Bean DataSource dataSource() { return new HikariDataSource(); }
    @Bean OrderRepository orderRepository(DataSource ds) {   // inject, don't call
        return new OrderRepository(ds);
    }
}
  • proxyBeanMethods = true (default). Spring generates a CGLIB subclass of the config class. Calling dataSource() from another @Bean method is intercepted and routed through the container's singleton cache, so you always get the one shared bean. Costs: proxy creation at startup, and the class can't be final.
  • proxyBeanMethods = false. No CGLIB subclass is created. @Bean methods behave like plain Java methods — calling one directly returns a brand-new object that the container never manages. Spring still registers each @Bean's return value as a bean; it just doesn't enforce singleton semantics on intra-class calls.

When to set false

Set false when your @Bean methods don't invoke each other — instead they receive their dependencies as method parameters (the recommended style anyway). In that case the proxy buys you nothing, so skipping it gives:

  • Faster startup / lower memory — no CGLIB class generation per config. At scale (many config classes) this is measurable, which is why Spring Boot's own auto-configuration classes are almost all @Configuration(proxyBeanMethods = false).
  • Native-image / AOT friendliness — fewer runtime-generated classes helps GraalVM.

The danger if you set it wrong

If you set proxyBeanMethods = false and still call a @Bean method from another one, you silently get duplicate instances — exactly the multi-DataSource-pool bug the proxy was protecting you from.

@Configuration(proxyBeanMethods = false)
public class Broken {
    @Bean DataSource dataSource() { return new HikariDataSource(); }
    @Bean OrderRepository repo() {
        return new OrderRepository(dataSource());  // BUG: a 2nd, unmanaged pool!
    }
}

The fix is always the same: pass the dependency as a parameter (repo(DataSource ds)), letting the container inject the managed singleton, rather than calling the method.

Mark your status