简体   繁体   中英

How do I keep the value of a static class variable in Spring?

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?

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.

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"/>

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.

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:

You should use something like AtomicInteger for this, it will allow threadsafe incrementing and provide visibility guarantees.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM