Spring @Autowire 与 getBean(className) 的性能

Performance of Spring @Autowire vs 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,只是简单的 class)? Autowiring 是否与 getBean 一样?

P.S。我想我应该稍微扩展一下我的问题。情况是我加入的团队只通过getBean(className)在项目中使用Spring注入。我猜的原因是大多数项目 classes 已经写的不是 Spring beans 并且在一个 class 中使用自动装配意味着通常也依赖 class bean 等等直到大多数 classes 变成 beans...

好的,我想我理解这种方法的可测试性损失和整体缺乏代码风格。但是不也有性能损失吗?准备就绪的 Spring 单例的性能在启动时构建并自动装配所有字段和调用 getBean(classname) 之间没有区别吗(afaik 比纯 [=23 慢几倍) =](object)) 来自非spring非单例class(特别是在关键地方)?

P.S.S.我创建了类似迷你基准的 smth(我知道由于 GC、JIT 等的工作,很难获得真实信息,但无论如何......)。 我的结果是(数字越大 - 越差): 自动装配时间 - 193,GetBean 时间 - 2161,同一方法 class - 173,另一个静态方法 class - 206

IMO,你不应该使用这些。正如一些用户已经在评论中提到的那样,你不应该关心表演。但是为了可测试性,使用基于构造函数的注入(@Autowired 是隐式的):

@Component
public class MyClass {

  private final AnotherClass object;     

  public MyClass(AnotherClass object) {
    this.object = object;
  }
}

每次需要访问 bean 时都在 Spring 上下文(通常是复合的)中查找 bean 效率很低。您实质上是在多个哈希表中多次查找一个项目,扰乱 CPU 缓存,浪费时间并可能阻止其他优化,例如由于更复杂的执行路径而导致的内联。

绝对使用自动装配(基于注解或基于构造函数)。这样查找在应用程序启动时完成一次,然后通过直接引用访问 class。

即使使用 @Autowired 注释,可测试性也非常好。您只需自动装配模拟而不是实际对象。还要查看 Mockito and Spring-Test 注释以注入模拟,否则会增加 Spring 上下文以进行测试。