【发布时间】:2021-11-06 21:38:41
【问题描述】:
我正在研究 Spring 框架,我看到了一些我无法解释实际发生的事情。 假设我们有这个简单的服务类:
@Service
@Scope(scopeName = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RandomNumberGenerator {
double number;
public RandomNumberGenerator() {
System.out.println("Constructor is called!");
number = Math.random();
}
public double getNumber() {
return number;
}
}
以及使用上述服务的以下控制器:
@RestController
public class NumberController {
@Autowired
RandomNumberGenerator numberGenerator;
@GetMapping(path = "/number")
public double getNumber(){
System.out.println(System.identityHashCode(numberGenerator));
return numberGenerator.getNumber();
}
}
我假设每个请求都会创建一个新的 RandomNumberGenerator numberGenerator 实例,因此我应该在 System.out.println(System.identityHashCode(numberGenerator)); 中打印不同的数字,但奇怪的是,每个请求都得到相同的数字,但我可以看到每个请求构造函数RandomNumberGenerator 被调用!
例如你可以看到我的控制台输出:
257434344
Constructor is called!
257434344
Constructor is called!
257434344
Constructor is called!
257434344
Constructor is called!
257434344
Constructor is called!
257434344
Constructor is called!
257434344
Constructor is called!
257434344
Constructor is called!
257434344
Constructor is called!
257434344
Constructor is called!
257434344
Constructor is called!
257434344
我的问题是为什么即使调用了构造函数,我也会得到相同的数字? System.out.println(System.identityHashCode(numberGenerator)) 不是应该返回不同的整数吗?
【问题讨论】:
-
@josejuan 控制器给我们一个不同的号码,但这条线
System.out.println(System.identityHashCode(numberGenerator));打印相同的号码。我在问题中添加了控制台输出 -
Spring 仅使用代理对象初始化
numberGenerator字段一次,该代理对象在内部知道如何创建RandomNumberGenerator类型的新实例并将getNumber调用委托给。但是,identityHashCode方法适用于代理对象,而不适用于新对象。 -
@josejuan OP 的印象是,
numberGenerator始终是每个请求的新对象。 -
@josejuan 我想要一种机制来区分实例,我搜索了stackoverflow,他们建议使用
System.identityHashCode