Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use @Configuration(proxyBeanMethods=false) wherever possible #9068

Closed
philwebb opened this issue May 3, 2017 · 14 comments
Closed

Use @Configuration(proxyBeanMethods=false) wherever possible #9068

philwebb opened this issue May 3, 2017 · 14 comments
Assignees
Labels
theme: performance Issues related to general performance type: enhancement A general enhancement
Milestone

Comments

@philwebb
Copy link
Member

philwebb commented May 3, 2017

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.

@philwebb philwebb added for: team-call type: enhancement A general enhancement labels May 3, 2017
@philwebb
Copy link
Member Author

philwebb commented May 3, 2017

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.

@philwebb
Copy link
Member Author

philwebb commented May 3, 2017

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)

@snicoll
Copy link
Member

snicoll commented May 3, 2017

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?

@philwebb
Copy link
Member Author

philwebb commented May 4, 2017

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.

@philwebb philwebb added status: on-hold We can't start working on this issue yet and removed for: team-call labels May 4, 2017
@iNikem
Copy link

iNikem commented May 5, 2017

@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 :)

@wilkinsona
Copy link
Member

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

@iNikem
Copy link

iNikem commented May 5, 2017

@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

@wilkinsona wilkinsona added the theme: performance Issues related to general performance label Feb 6, 2019
@bclozel bclozel changed the title Improve performance by replacing @Configuration with @Component Investigate startup time difference between @Configuration and @Component configuration classes Feb 6, 2019
@wilkinsona wilkinsona added type: task A general task and removed status: on-hold We can't start working on this issue yet type: enhancement A general enhancement labels Feb 6, 2019
@wilkinsona wilkinsona added this to the 2.2.x milestone Feb 6, 2019
@wilkinsona
Copy link
Member

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

@wilkinsona
Copy link
Member

wilkinsona commented Feb 7, 2019

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.

@wilkinsona wilkinsona self-assigned this Feb 7, 2019
@wilkinsona wilkinsona added for: team-attention An issue we'd like other members of the team to review and removed for: team-attention An issue we'd like other members of the team to review labels Feb 8, 2019
@wilkinsona wilkinsona changed the title Investigate startup time difference between @Configuration and @Component configuration classes Use @Configuration(proxyBeanMethods=false) wherever possible Mar 8, 2019
larsgrefer added a commit to larsgrefer/joinfaces that referenced this issue Oct 28, 2019
srempfer added a commit to srempfer/spring-cloud-config-azure-keyvault that referenced this issue Nov 3, 2020
atanava referenced this issue in ivol84/geo-locator Feb 23, 2022
@hefreecola
Copy link

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

@bclozel
Copy link
Member

bclozel commented Apr 15, 2022

@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.

tejada7 added a commit to tejada7/spring-certification that referenced this issue May 9, 2023
As part of performance start-up time improvement, Spring 5.2 brings the option to disable the cglib proxy, allowing henceforth configuration classes to be final.

Mind that inner-class bean method call are no longer possible since no proxy will ensure the unique instance (if bean scope defaulted to singleton).

Reference: spring-projects/spring-boot#9068
tejada7 added a commit to tejada7/spring-certification that referenced this issue May 9, 2023
As part of performance start-up time improvement, Spring 5.2 brings the option to disable the cglib proxy, allowing henceforth configuration classes to be final.

Mind that inner-class bean method call are no longer possible since no proxy will ensure the unique instance (if bean scope defaulted to singleton).

Reference: spring-projects/spring-boot#9068
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
theme: performance Issues related to general performance type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

6 participants