按类型划分的弹簧布线比按名称布线要慢

min*_*das 24 java performance spring dependency-injection autowired

在我的项目中,我正在尝试迁移所有用法

Foo foo = (Foo) beanFactory.getBean("name");
Run Code Online (Sandbox Code Playgroud)

Foo foo = beanFactory.getBean(Foo.class);
Run Code Online (Sandbox Code Playgroud)

好处是显而易见的:类型安全性,较少复杂的代码,较少的无用常量等.通常,这些线路位于静态遗留环境中,其中这种布线是唯一的选择.

这一切都很好,直到有一天用户开始抱怨来自Spring internals的缓慢.所以我启动了一个分析器来找到一个热点

org.springframework.beans.factory.support.AbstractBeanFactory::doGetBean(String, Class<T>, Object[], boolean)

这是一个昂贵的电话

Class.isAssignableFrom(anotherClass).

我已经快速创建了一个小的性能测试,以找出字符串名称和类型查找之间的速度差异是一个百日咳350次(我正在使用StaticApplicationContext这个测试FAIW)!

在调查这一点时,我发现SPR-6870的票数很高,但由于某种原因没有得到解决.这导致我试图解决这个问题,这个问题确实显着改善了这种情况,但仍然比String查找慢了~25倍!事实证明,这种尝试只解决了一半的问题:它缓存了bean的名称以保存在O(n)迭代上,但仍然需要调用isAssignableFrom来验证类型.

所描述的问题不仅与我的场景有关,而且也适用@Autowired于在循环内创建bean的情况下使用并且可能感觉很难的bean.

其中一个解决方案是覆盖其中一个bean工厂方法并缓存同一类型的is-this-bean类型的检查结果,但显然这应该在Spring中完成而不是在我自己的代码中完成.

是否还有其他人遇到类似问题并找到解决方案?

Chr*_*ams 5

现在用Spring -SPR70的分辨率解决了这个问题.有关详细信息,请参阅其中的分辨率 从版本3.2.0.RELEASE和3.1.2开始提供此修复程序.