In my project, I am trying to migrate all usages of
Foo foo = (Foo) beanFactory.getBean("name");
into
Foo foo = beanFactory.getBean(Foo.class);
The benefits are obvious: type safety, less convoluted code, less useless constants, etc. Typically such lines are located in static legacy contexts where such a wiring is the only option.
This was all fine until one day users started to complain about the slowness which turned out to come from Spring internals. So I fired up a profiler to find a hotspot in
org.springframework.beans.factory.support.AbstractBeanFactory::doGetBean(String, Class<T>, Object[], boolean)
which has an expensive call to
Class.isAssignableFrom(anotherClass)
.
I have quickly created a small performance test to find out the speed difference between string name and type lookups is a whooping 350 times (I'm using StaticApplicationContext
for this test FAIW)!
While investigating this, I found SPR-6870 which has high number of votes but for some reason isn't addressed. This led me to an attempt to solve this problem which does significantly improve the situation but is still slower ~25 times than lookup by String! It turns out this attempt only solves half of the problem: it caches the name of the bean to save on O(n) iteration but still has to do call isAssignableFrom
to validate the type.
Described problem is not only related to my scenario but is also for beans which use @Autowired
and can be felt hard in cases where beans are created inside a loop.
One of solutions would be to override one of the bean factory methods and cache the is-this-bean-of-the-same-type check results but clearly this should be done in Spring and not in my own code.
Is anyone else suffering from a similar problem and found a solution to it?
In Spring, 5 Auto-wiring modes are supported. byName – Auto wiring by property name. If the name of a bean is same as the name of other bean property, auto wire it.
So, Spring is able to utilize the BeanFactory to know the dependencies across all the used beans. The XML-configuration-based autowiring functionality has five modes – no , byName , byType , constructor , and autodetect .
The @Autowired annotation provides more fine-grained control over where and how autowiring should be accomplished. The @Autowired annotation can be used to autowire bean on the setter method just like @Required annotation, constructor, a property or methods with arbitrary names and/or multiple arguments.
The default mode of Spring's traditional XML-based configuration is 'no' i.e no auto wiring is enabled by default. But, if you choose to use annotation-based configuration(<context:annotation-config>), & for instance, if you are using @Autowired , then the default method of auto wiring for this is "byType".
This problem is now solved in Spring with the resolution of SPR-6870. See the resolution comments there for details. The fix is available as of versions 3.2.0.RELEASE and 3.1.2.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With