有两种代码变体:
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类,而是简单的类)? 自动装配与getBean一样吗?
P.S。我想我应该扩大我的问题。情况是,我加入的团队仅通过getBean(className)在项目中使用Spring注入。我猜想原因是大多数已编写的项目类都不是Spring Bean,并且在一个类中使用自动装配通常意味着也要制作依赖类Bean,依此类推,直到大多数类成为Bean ...
好吧,我想我了解可测试性的惩罚以及这种方法的整体代码风格的缺失。但是,是否没有性能惩罚als®?在启动时构建的具有自动连接的所有字段的即兴Spring Singleton的性能与从非Spring Non中调用getBean(classname)(比纯hashmap.get(object)慢几倍)之间的性能之间没有区别-单班(特别是在关键地方)?
P.S.S。我创建了像迷你基准之类的东西(我知道由于GC,JIT等的工作很难获得真实的信息,但是……)。 我的结果是(数字越大-越差): 自动装配时间-193,GetBean时间-2161,同一类中的方法-173,另一类中的静态方法-206
答案 0 :(得分:1)
IMO,您不应使用其中任何一种。正如一些用户在评论中已经提到的那样,您不应该关注表演。但是为了可测试性,请使用基于构造函数的注入(并且@Autowired是隐式的):
@Component
public class MyClass {
private final AnotherClass object;
public MyClass(AnotherClass object) {
this.object = object;
}
}
答案 1 :(得分:0)
我同意Oreste Viron尝试使用基于构造函数的注入。 但是关于你的问题。没有性能损失。
答案 2 :(得分:0)
每次需要访问它时,在Spring上下文(通常是复合的)中查找bean效率低下。本质上,您需要多次在多个哈希表中查找项目,从而浪费了CPU缓存,浪费了时间,并可能由于更复杂的执行路径而阻止其他优化(如内联)。
一定要使用自动装配(基于注释或基于构造函数)。这样一来,查找就在应用程序启动时完成一次,然后通过直接引用访问该类。
即使使用@Autowired
批注,可测试性也很好。您只需自动装配模拟而不是实际对象即可。另外,请查看Mockito和Spring-Test批注以注入模拟内容,或出于测试目的扩展Spring上下文。