所以我有这个班级的例子:
public class Test {
private static int idCounter;
private int id;
Test() {
id=++idCounter;
}
public void getId() {
System.out.printf("This id is %s",this.id);
}
}
beans.xml config:
<beans>
<bean id="test" class="com.Test"/>
</beans>
现在,当我尝试创建一个ArrayList时,静态变量每次都会重置。
for (int i=0;i<9;i++) {
arrayList.add(context.getBean("test");
arrayList.get(i).getId();
}
它将打印出#34;这是1&#34;对于arrayList中的每个对象。我怎样才能使静态变量保持全局值?
答案 0 :(得分:2)
这里发生的事情不是你想象的那样。静态成员变量没有重置;你的Test
bean只有一个实例,在循环中你会查找相同的Test
bean十次。
Spring bean默认具有singleton范围,这意味着Spring只会创建一个bean实例,每次注入或查找时都会使用它。如果您希望每次都创建一个新实例,请给出bean原型范围而不是默认的单例范围:
@Scope("prototype")
public class Test {
// ...
}
如果使用XML配置Spring bean,那么就像Andrew Logvinov在他的回答中所显示的那样;添加scope
属性:
<bean id="test" class="com.Test" scope="prototype"/>
要了解更多信息,请参阅Spring Framework参考文档中的Bean scopes。
答案 1 :(得分:1)
默认情况下,Spring bean具有单例作用域,这意味着每个请求都返回相同的bean实例。你需要的是一个原型范围:
<bean id="myBean" class="com.test.MyClass" scope="prototype"/>
答案 2 :(得分:0)
您已使用test
id:
<beans>
<bean id="test" class="com.Test"/>
</beans>
但是之后你会使用id triangle
得到另一个bean的实例:
context.getBean("triangle")
所以,我想,这只是错字错误:你获得了另一个bean的实例,你没有静态id计数器。如果我不对,请检查您的代码并更新问题。
答案 3 :(得分:0)
Jesper's answer是对的;因为你把它配置为单例,只有一个类的实例,构造函数被调用一次。
然而,即使您修复此问题以使用原型范围,它也可能无法正常工作,原因有两个:
++运算符不是线程安全的,请参阅Is the pre-increment operator thread-safe?。
没有任何东西强迫您的计数器更新在线程中可见。
你应该使用AtomicInteger这样的东西,它将允许线程安全递增并提供可见性保证。