Spring Singleton, Request, Session Beans and Thread Safety

The Spring framework ecosystem comprising of so many useful frameworks has become the backbone of many Java EE application. But at the core of all the spring products we still have the Spring DI/IOC framework which has catapulted Spring to all new heights. As more people are adopting Spring MVC or a JSF-Spring integration for their application, the Spring beans are now more frequently used with request/session scope apart from their more traditional counterparts of Singleton and  Prototype scopes.

One of the initial curiosities of a developer just starting out with various Spring scopes is that how do these scope behave in a web application and in situations which require writing safe concurrency code. Well the answer to this no to over-think about these scope as they behave exactly the way they have been named.  Let’s take a example of JSF- Spring integration wherein all the JSF beans are loaded by the Spring IOC container and Scope of the beans are also defined using suppose Spring’s @Scope annotation.

The bean with @Scope(“request”) would be created for anywhere new incoming request thus it’s thread safely is guaranteed since it’s created everytime a new request comes in. Next is the @Scope(“session”) bean which would be same for every session of the user, in case of user accessing the application through multiple tabs of the browser this bean scope can surely give concurrency issues thus it’s important for the developer to make sure that the state of the shared session data doesn’t become corrupt.

Now comes the @Scope(“singleton”)  or the default scope of the Spring beans, how do these singleton beans behave in a heavy load web application.  Well first of all it’s important to understand that “Singleton” means only one instance i.e. the application will have only one instance of that bean. Now Spring framework doesn’t do anything under the hood concerning the multithreaded  behavior this Singleton bean i.e. it’s just a normal Singleton bean and it’s upto the developer to handle the Concurrency issues pertaining to this bean

Now the question arises what kind of beans should be Singleton in a web application, well the answer is pretty straightforward Any Bean without a STATE can be singleton .  For example beans that easily qualify to be singleton are DAO,  Service ,  Controller these beans don’t have their own states instead we leverage these beans in our application to perform certain operations..  The DAO layer beans can be singleton as they don’t have their own state but every thread accessing them using the DAO bean to perform certain thread specific operation thus the DAO bean remains unaffected by it’s own concurrent access because it doesn’t have it’s own state.

A really bad example of choosing a Singleton bean would be a bean that needs to maintain it’s state in that case each thread would try to impose it’s own state on that bean there by corrupting the data.  For Example if a Person bean with setters and getter for name and age is made singleton. Now if multiple threads start accessing this bean they would keep overriding the last set values of the Person’s instance thereby corrupting the state.

ConclusionRemember the golden rule choose only those beans as singleton that don’t have state.

PS: If you have faced any anomalies related to spring scopes in a web application, please do share them. Thanks!

About Tarun Sapra
Agile Java developer @ Xebia India

16 Responses to Spring Singleton, Request, Session Beans and Thread Safety

  1. Nice Blog Tarun. Apart from the tech stuff, I really liked the flow of the blog.

  2. Josh Long says:

    Tarun, this is a really great post! I would add that singleton Spring beans themselves can maintain their *own* state, it’s just that care (as you indicate) must be taken in guarding against potentially concurrent, *client-specific* state. There are examples of this in Spring itself: one common example is the support for the JPA EntityManager (which is *not* thread-safe), which, when used (e.g., @PersistenceContext EntityManager em) actually injects a proxy, which in turn forwards to a thread-local EnittyManager. So, each client gets their own thread-local-bound (which is appropriate: the JPA spec recommends that the client unit-of-work / session map 1:1 to an accquired EntityManager), but the developer just writes single-threaded code using that EntityManager. There are places like this all over the place so that developers get the best of both worlds: the speed of non-synchronized access on a singleton, and the safety of single-threaded access, where required. 99% of the time, you never need to know about it, of course 😉

  3. Harsh Gupta says:

    I was using prototype beans in my project because i want new object. Actually it was a list where all my prototype beans are getting stored. But I had to use getBean() of applicationcontext to make it work, to actually get the new object, otherwise without calling getBean() method it returned same object and worked like singleton. I didn’t realize this until my project went to production.

    • Tarun Sapra says:

      From spring docs “However, the bean properties themselves are not set until the bean is actually created. For beans which are singleton and set to be pre-instantiated (such as singleton beans in an ApplicationContext)” .

      Singleton beans are initialized when applicationContext is initialized, but to initialize prototype bean you would have to do getBean(“BeanNameofPrototypebean”)

  4. Thank you for this helpful article

  5. vinod says:

    very helpful post.

  6. Marco says:

    Very good article!

    So.. if I have a class that generates pdf report given an entity id and I want to inject it into a controller I should declare the bean scope as request.. or I have to synchronize the method that generate.

    Have I understand in a correct way?

    Thank you!

    • Tarun Sapra says:

      Hello Marco,

      Why would you inject it in a controller? Controllers are generally used to delegate the control further to the logic/action beans. Let the controller delegate it to a request or prototype instance which handles the logic or generates the pdf. This would also be thread-safe as for every new request you have request scope bean.

  7. Sushant says:

    Nice post … got some of my doubts clarified regarding use of singleton and request scope.

  8. Anand Kumar says:

    Hello Tarun:

    I came across your blog today and it did clear some of my doubts but if you still have time, can you please answer two of my questions below:

    1. You mention that all the controllers, service layers and DAOs should qualify as singleton classed. How about the model objects? Since they hold the state of the object they are representing in a JAVA spring MVC application, per you they shouldn’t be declared as singleton? Should they be declared as request then?

    2. I have a typical spring MVC application and might have thousands of concurrent request at times. In a typical scenario, my application receives a request, makes a web service call, gets the response in JSON format and parses it before returning the response to the client application. Now for parsing purpose, I am using the simple parser class org.json.simple.parser.JSONParser (https://code.google.com/p/json-simple/source/browse/trunk/src/org/json/simple/parser/JSONParser.java?r=73). Can I declare this class as singleton or it should be request type? If you look at the class, it does maintain some states but upon calling the parser method, first time it clears all the states. Still I think, in concurrent requests, we might run into problem.

    Sorry for long type, but I need some insight. Please help.

  9. Swetha says:

    What a good post ,clarified my doubts thanks alot

  10. Monica says:

    thanks,nice post.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: