springspring-bootspring-boot-configurationspring-autoconfiguration

Why does @AutoConfiguration use proxyBeanMethods = false, @AutoConfigureBefore, @AutoConfigureAfter


Spring Boot auto configuration was recently changed with version 2.7 and most of the settings deprecated with version 3.0 (you can find details here). Also, they introduced new annotation for auto configuration classes which is @AutoConfiguration. I couldn't understand default settings of the annotation which stated below:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration(proxyBeanMethods = false)
@AutoConfigureBefore
@AutoConfigureAfter
public @interface AutoConfiguration {
}

Why they enforced users to inherit proxyBeanMethods = false, @AutoConfigureBefore and @AutoConfigureAfter?


Solution

  • The reason we default to proxyBeanMethods=false is because we think that is the most sensible default for auto-configuration classes. It means that less processing time is required when starting the application.

    Say you have a configuration like this:

    @Configuration(proxyBeanMethods=true)
    class MyConfiguration {
    
        @Bean
        MyBean1 myBean1() {
            return new MyBean1(myBean2());
        }
    
        @Bean
        MyBean2 myBean2() {
            return new MyBean2();
        }
    
    }
    

    In this case Spring must dynamically create CGLIB subclass of MyConfiguration just to ensure that any call to myBean2() actually delegates to the BeanFactory.

    This means that additional bytecode needs to be generated and loaded as the application starts.

    If you rewrite the configuration as follows:

    @Configuration(proxyBeanMethods=false)
    class MyConfiguration {
    
        @Bean
        MyBean1 myBean1(MyBean2 myBean2) {
            return new MyBean1(myBean2);
        }
    
        @Bean
        MyBean2 myBean2() {
            return new MyBean2();
        }
    
    }
    

    Not only do you save resources, but the code is more honest about what it is actually doing.

    If you really really want to continue to use proxy classes you can continue to use @Configuration. Classes loaded from entries in the META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports file do not actually need to be annotated with @AutoConfiguration.