【发布时间】:2012-03-14 20:03:49
【问题描述】:
在我的项目中,我正在尝试迁移
Foo foo = (Foo) beanFactory.getBean("name");
进入
Foo foo = beanFactory.getBean(Foo.class);
好处是显而易见的:类型安全、更少复杂的代码、更少无用的常量等。通常,此类行位于静态遗留上下文中,这种布线是唯一的选择。
这一切都很好,直到有一天用户开始抱怨原来来自 Spring 内部的缓慢。所以我启动了一个分析器来在
中找到一个热点org.springframework.beans.factory.support.AbstractBeanFactory::doGetBean(String, Class<T>, Object[], boolean)
调用昂贵的
Class.isAssignableFrom(anotherClass).
我快速创建了一个小型性能测试,以找出字符串名称和类型查找之间的速度差异是 350 倍(我使用 StaticApplicationContext 进行此测试 FAIW)!
在调查此问题时,我发现 SPR-6870 的投票数很高,但由于某种原因没有得到解决。这让我找到了an attempt to solve this problem,它确实显着改善了这种情况,但仍然比通过字符串查找慢 ~25 倍!事实证明,这种尝试只解决了一半的问题:它缓存了 bean 的名称以保存 O(n) 迭代,但仍然需要调用 isAssignableFrom 来验证类型。
所描述的问题不仅与我的场景有关,而且还与使用 @Autowired 的 bean 相关,并且在循环内创建 bean 的情况下会感到困难。
解决方案之一是覆盖其中一个 bean 工厂方法并缓存 is-this-bean-of-the-same-type 检查结果,但显然这应该在 Spring 中完成,而不是在我自己的代码中。
是否有其他人遇到类似问题并找到了解决方案?
【问题讨论】:
-
那么,你想按类型自动装配,但不做任何类型检查?
-
我希望对同一类型进行第二次调用,以避免昂贵的类型检查。或者至少我希望能够指定这是启用还是禁用。对象创建是如此基本的事情,像这样的小优化可以产生很大的不同。
标签: java performance spring dependency-injection autowired