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();
}
}

第一个变体中会有任何性能惩罚(顺便说一句,这不是弹簧bean,只是简单的类)吗?AutoWiring与GetBean相同吗?

P.S。我想我应该扩大我的问题。情况是,我加入的团队仅通过GetBean(className)在项目中使用弹簧注入。我猜想的原因是,已经编写的大多数项目类都不是弹簧豆,并且在一个类中使用自动播种,通常也可以制作依赖的类bean,依此类推,直到大多数类变成bean ...

好吧,我认为我了解可检验性罚款,并且总体上缺乏这种方法的代码风格。但是,没有罚款吗?在启动上构建的所有自动化和调用getBean(className)(afaik)(afaik慢了几次较慢的pure hashmap.get(object)),在启动上构建的即时春季单人顿的性能之间是否有区别 - Singleton类(尤其是在关键的地方)?

P.S.S。我创建了SMTH,例如Mini-Benchmark(我知道由于GC,JIT的工作等,很难获得真实的信息,但是...)。我的结果是(数字更大 - 更糟):自动时间-193,GetBean Time -2161,同一类中的方法-173,另一类静态方法-206

每次您需要访问它时,在春季上下文(通常是复合)中查找bean的效率将是低效的。实际上,您要多次查找多个哈希表中的项目,触摸CPU缓存,浪费时间并有可能阻止其他优化,例如由于更复杂的执行路径而嵌入。

绝对使用AutoWOWINing(基于注释或基于构造函数)。这样,查找一次在应用程序启动时完成一次,然后通过直接参考访问该类。

即使使用@Autowired注释,可检验性也完全可以。您只需自动模拟而不是实际对象即可。还要查看嘲笑和春季测试注释以注入模拟并以其他方式增加春季上下文以进行测试。

imo,您不应使用任何此类。正如一些用户在评论中已经提到的那样,您不应该照顾表演。但是对于可测试性,请使用基于构造函数的注入(并且@Autowired是隐式的):

@Component
public class MyClass {
  private final AnotherClass object;     
  public MyClass(AnotherClass object) {
    this.object = object;
  }
}

最新更新