Almost all of our auto-configuration classes are currently annotated with @Configuration. The means that the ConfigurationClassPostProcessor will treat them as full configuration classes and create cglib proxies.

This is potentially quite an expensive operation and is unnecessary for most of them. As long as we use parameter injection (and don't call other methods directly) we can use the @Component annotation instead to create ConfigurationClassUtils.CONFIGURATION_CLASS_LITE configuration.

Comment From: philwebb

See https://github.com/philwebb/spring-boot/tree/gh-9068 for an example. Tests still appear to pass on this branch.

Startup time for SampleActuatorApplication is about 150-200ms faster.

Comment From: philwebb

Some java -jar timings on the actuator UI sample:

Master:

2017-05-02 22:09:59.733  INFO 93667 --- [           main] s.a.ui.SampleActuatorUiApplication       : Started SampleActuatorUiApplication in 3.136 seconds (JVM running for 3.491)
2017-05-02 22:10:19.132  INFO 93734 --- [           main] s.a.ui.SampleActuatorUiApplication       : Started SampleActuatorUiApplication in 3.156 seconds (JVM running for 3.507)
2017-05-02 22:10:27.976  INFO 93795 --- [           main] s.a.ui.SampleActuatorUiApplication       : Started SampleActuatorUiApplication in 3.15 seconds (JVM running for 3.502)

Branch:

2017-05-02 22:14:43.020  INFO 94861 --- [           main] s.a.ui.SampleActuatorUiApplication       : Started SampleActuatorUiApplication in 3.123 seconds (JVM running for 3.483)
2017-05-02 22:14:55.886  INFO 94922 --- [           main] s.a.ui.SampleActuatorUiApplication       : Started SampleActuatorUiApplication in 3.095 seconds (JVM running for 3.454)
2017-05-02 22:15:11.822  INFO 94989 --- [           main] s.a.ui.SampleActuatorUiApplication       : Started SampleActuatorUiApplication in 2.979 seconds (JVM running for 3.342)
2017-05-02 22:17:49.842  INFO 95138 --- [           main] s.a.ui.SampleActuatorUiApplication       : Started SampleActuatorUiApplication in 2.921 seconds (JVM running for 3.269)

Comment From: snicoll

Isn't that going a tad too far? I understand the performance argument but reading an auto-configuration flagged as a component is very odd. And the lite mode is something I am not sure we should advertize.

What are you going to write in the user guide to justify such move?

Comment From: philwebb

The @Component route may be a bit confusing. I've raised SPR-15512 to see if the annotation idea that @snicoll had on the call might work.

Comment From: iNikem

@philwebb are you sure that the performance changes that you presented are not just statistically insignificant fluctuations? Change of 3% or 100ms seems like a noise :)

Comment From: wilkinsona

@iNikem How do you draw that conclusion without knowing by how much the timings usually fluctuate? Do you have some additional data to share?

Comment From: iNikem

@wilkinsona I don't have more data. I just saw the comment above where @philwebb showed time measurements from 7 runs. IMO 7 data points is never enough to draw any conclusions about performance

Comment From: wilkinsona

While we're still not keen on using @Component rather than @Configuration as the means, the end result continues to be worth pursuing. The following tables are for the startup time of the WebFlux sample:

Fat jar:

Baseline New
2.437 2.188
2.433 2.027
2.339 2.169
2.276 1.983
2.381 2.249
2.341 2.125
2.328 2.063
2.344 2.083
2.345 2.045
2.277 2.095
Mean 2.350 2.103
Range 0.161 0.266

Main method:

Baseline New
2.108 1.868
2.051 1.877
2.112 2.032
2.039 1.843
2.151 1.842
2.139 1.857
2.119 1.897
2.075 1.917
2.113 1.917
2.210 1.900
Mean 2.112 1.895
Range 0.171 0.190

Comment From: wilkinsona

The following classes in Spring Boot require proxying as they have one or more @Bean methods that are called directly, rather than by Framework:

  • o.s.b.a.data.couchbase.SpringBootCouchbaseDataConfiguration
  • o.s.b.a.data.couchbase.SpringBootCouchbaseReactiveDataConfiguration
  • o.s.b.a.data.jdbc.JdbcRepositoriesAutoConfiguration$SpringBootJdbcConfiguration
  • o.s.b.a.session.RedisSessionConfiguration$SpringBootRedisHttpSessionConfiguration
  • o.s.b.a.web.reactive.WebFluxAutoConfiguration$EnableWebFluxConfiguration
  • o.s.b.a.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration

All of these are out of our control. In each case we sub-class a class from another project and it's the code in the super-class that means that a proxy is required.

We also have one class where the need for a proxy is, largely, self-inflicted:

  • o.s.b.a.couchbase.CouchbaseConfiguration

There are a few other classes in Boot that currently rely on proxying, but it's straightforward to change them so that they do not do so.

Comment From: wilkinsona

I've opened https://github.com/spring-projects/spring-boot/issues/16200 to rework CouchbaseConfiguration.

Comment From: wilkinsona

There was a quirk in Spring Framework that meant that a few configuration classes that defined factory beans still had to be proxied. That quirk has been fixed now. Re-opening to make the necessary updates once repo.spring.io is back on its feet and we can get at a new Framework snapshot.

Comment From: snicoll

As we're close to the release, let's follow-up on that in the next milestone. I've created #16533

Comment From: hefreecola

when use @Configuration(proxyBeanMethods = false) whill erro in my bean getOtherBean

Comment From: bclozel

@hefreecola this means you're probably relying on proxying (inter-bean methods calls). In this case, you shouldn't use this option. See javadoc. For further questions, please use StackOverflow.