Performance improvement in applicationContext.getBean() & AutoWired with complex beans [SPR-7988] #12643
Labels
in: core
Issues in core modules (aop, beans, core, context, expression)
status: bulk-closed
An outdated, unresolved issue that's closed in bulk as part of a cleaning process
Jose Luis Freire opened SPR-7988 and commented
In an effort to improve the response time of our application we did some profiling and found out that too much time was being consumed by the Spring Framework itself.
The time was being consumed with applicationContext.getBean(), because in our application we almost don't have session scoped beans and in one request multiple beans can be instantiated.
Our beans are all annotated, with multiple Autowired properties, with several advices to process, and the timing of one bean instantiation was about from 50ms (the most simpler ones) to 150ms (the more complex ones) each.
In many of our pages, the bean instantiation was responsible for more than half of the total processing time.
In our profiling we found that the hotspot was in AopUtils.canApply() method.
What the Spring Framework is doing is evaluating the bean by reflection every time the bean is created, and with complex objects that operation can be really expensive.
The answer is simple, we should cache those results, but due to the complexity of this method we didn't felt comfortable in evaluating what was cacheable, so we choose other targets:
We have very good results and we believe that in complex web applications where most of your beans aren't session scoped, the overall performance and responsiveness of the application can be greatly improved (in our tests, 10x).
What we're doing is trading memory for CPU.
To give credit where credit is due, we inspired our solution with Jonathan work (http://jawspeak.com/2010/11/28/spring-slow-autowiring-by-type-getbeannamesfortype-fix-10x-speed-boost-3600ms-to/)
Our test scenario is a simple page that instantiates the same bean 100 times. The total time dropped from more than 5s to about 500ms.
Attached is two screenshots of the profiler:
I'm also attaching the diffs for review.
By caching these two methods (AopUtils.getMostSpecificMethod(..), and AnnotationClassFilter.matches(..) and not AopUtils.canApply(..) we're probably giving a speed boost to all the framework, but I still believe that we must do some work with AopUtils, but I'll leave that to someone that understands more of the probable consequences.
Affects: 3.0.5
Attachments:
9 votes, 14 watchers
The text was updated successfully, but these errors were encountered: