java - Spring @Autowire 与 getBean(className) 的性能
问题描述
代码有两种变体:
public class MyClass {
public void myMethod() {
AnotherClass object = SpringContexHolder.getContext().getBean(AnotherClass.class);
object.doSomething();
}
}
@Component
public class MyClass {
@Autowired
AnotherClass object;
public void myMethod() {
object.doSomething();
}
}
第一个变体是否会有任何性能损失(顺便说一下,它不是spring bean,只是简单的类)?自动装配是否与 getBean 一样?
PS我想我应该稍微扩展一下我的问题。情况是我加入的团队只通过getBean(className)在项目中使用Spring注入。我猜的原因是大多数已经编写的项目类都不是 Spring bean,并且在一个类中使用自动装配意味着通常也会制作依赖类 bean,依此类推,直到大多数类变成 bean...
好的,我想我理解这种方法的可测试性惩罚和整体缺乏代码风格。但是难道没有性能惩罚吗?在启动时构建的即用型 Spring 单例的性能是否存在差异,它的所有字段都是自动装配的,并且从非 Spring 非- 单人班(特别是在关键地方)?
PSS 我创建了类似 mini-benchmark 的东西(我知道由于 GC、JIT 等的工作,很难获得真实的信息,但尽管如此......)。我的结果是(数字越大越差):自动装配时间 - 193,GetBean 时间 - 2161,同一类中的方法 - 173,另一个类中的静态方法 - 206
解决方案
每次需要访问时在 Spring 上下文(通常是复合的)中查找 bean 的效率会很低。您实际上是在多个哈希表中多次查找一个项目,破坏 CPU 缓存,浪费时间并可能由于更复杂的执行路径而阻止其他优化,例如内联。
绝对使用自动装配(基于注释或基于构造函数)。这样,在应用程序启动时进行一次查找,然后通过直接引用访问该类。
@Autowired
即使有注释,可测试性也很好。您只需自动装配模拟而不是实际对象。还要查看Mockito和Spring-Test注释以注入模拟并以其他方式增强 Spring 上下文以进行测试。
推荐阅读
- python - 与 FORTRAN shell 程序进行交互通信
- r - 在 pheatmap 的行上添加带有图例的颜色
- swift - SwiftUI 小部件 DateStyle 自定义格式
- wordpress - Wordpress子页面在windows子目录安装中给出404
- r - 基于多个条件的标志
- javascript - 将 If/Else 转换为三元 React Typescript
- java - 如何将现有的 Maven 项目作为多模块 Maven 项目的一部分?
- powershell - 在 PowerShell 中运行 PowerShell 脚本运行正确,但从调度程序运行时出错
- r - 使用 pagedown 创建的 xaringan PDF 中不需要的边距
- java - 参数化 Java JPA ALTER SESSION SQL