Reputation: 1465
so I have this class example:
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);
}
}
And the beans.xml config:
<beans>
<bean id="test" class="com.Test"/>
</beans>
Now when I try to make an ArrayList, the static variable resets every time.
for (int i=0;i<9;i++) {
arrayList.add(context.getBean("test");
arrayList.get(i).getId();
}
It will print that "This is is 1" for every object in the arrayList. How can I make it so that the static variable will keep it's global value?
Upvotes: 1
Views: 3048
Reputation: 96395
Jesper's answer is right; since you configured this as as singleton there is only one instance of the class, the constructor gets called once.
However, even once you fix that this to use prototype scope it may not work as you expect, for two reasons:
The ++ operator is not thread-safe, see Is the pre-increment operator thread-safe?.
There's nothing forcing the updates to your counter to become visible across threads.
You should use something like AtomicInteger for this, it will allow threadsafe incrementing and provide visibility guarantees.
Upvotes: 0
Reputation: 34900
You have declared you bean with test
id:
<beans>
<bean id="test" class="com.Test"/>
</beans>
But after that you get instance of some another bean using id triangle
:
context.getBean("triangle")
So, I suppose, this is just typo-error: you obtain instance of some another bean, where you don't have static id counter. Check you code and update question if I'm not right.
Upvotes: 0
Reputation: 206816
What is happening here is not what you think is happening. The static member variable is not resetting; there is only one instance of your Test
bean, and in the loop you are looking up the same Test
bean ten times.
Spring beans by default have singleton scope, which means Spring will create only one instance of the bean, which is used every time it is injected or looked up. If you want a new instance created every time, give the bean prototype scope instead of the default singleton scope:
@Scope("prototype")
public class Test {
// ...
}
If you configure your Spring beans using XML, then do it as Andrew Logvinov shows in his answer; add a scope
attribute:
<bean id="test" class="com.Test" scope="prototype"/>
To learn more, see Bean scopes in the Spring Framework reference documentation.
Upvotes: 2
Reputation: 21831
By default, Spring beans have singleton scope, meaning each request returns same instance of bean. What you need is a prototype scope:
<bean id="myBean" class="com.test.MyClass" scope="prototype"/>
Upvotes: 1