I know this question may sound naive, but I have a confusion regarding the scope of bean in web application.
I know that for every request a new thread is spawned by the container similarly in case of a spring web application a new thread is spawned for every request, then why it is suggested to define my controller, service as singleton, shouldn't the scope of these beans be prototype, because each request i.e. thread will have their own instance of controller, service to work with.
Please enlighten me.
That would be a huge amount of overhead. There's no reason why each request needs its own service bean if you make your code properly thread-safe, which usually just means not keeping any per-request state on the bean.
Even though a new thread is created (or re-used depending on the configuration), the controller and service instances are re-used. If the controllers and services are designed well, they can be stateless with respect to the request and immutable, which will make them thread-safe. It would also lead to far less object creations when their state is not going to change after their creation.
https://gottalovedev.wordpress.com/2014/11/23/bean-scope/
Give this a read. I'm sure it would help.
I think this really depends whether you need to store any state in your bean. Usually, I write my singletons so that they contain no state inside of it and are only used to compute business logic. Without state needing to be managed, then it is acceptable to have all threads share that one singleton instance.
Related
I am really sorry to ask such a question, but I need a bit of your help.
As far I understand, if I use servlets all my business logic ( methods of which I call in controllers ) should be Thread-safe.
Does the same count for Spring? Do I need to make thread-safe methods in service layer when I use #Getmapping #PostMapping instead of using servlets directly?
I do appreciate your help a lot!
Thread safety is a different context . Singleton spring beans(default scope) has no relation with thread safety. Spring container only manages life-cycle of objects and guaranteed that only one object in spring container. So, if a Non thread safe object is injected then obviously it is not thread safe. To make it thread safe you have to handle it by coding.
If it is a web-application , Scope - request can achieve thread-safety as for each new request it creates a new object or Scope - prototype will do this.(for each invocation it creates new bean .)
Probably the stupidest question you have ever heard.
Inside the Web container how more than 1 object of the same class is getting created/managed which has same reference variable... Let me explain with an example.
Inside my controller class I have a code piece
AdminUser adminUser= new AdminUser();
So when 2 Admins signs-in to my web application, there will be 2 Objects of the class AdminUser with same reference variable "adminUser"
How is it possible, is it 2 different threads?
Who is managing this threads, web container?
If so, how web container is doing it, is it wrapping application
code with threadLocal?
If its different threads, to maintain a global object (say a counter
for the admins visit counts), "static" won't suffice... it needs to be
"volatile" instead, correct?
So when 2 Admins signs-in to my web application, there will be 2 Objects of the class AdminUser with same reference variable "adminUser"
No.
If that line of code is in a method, the variable is on the stack, and there can be as many instances as there are concurrent invocations of the method, including recursions and calls by multiple threads.
If it's non-static member initialization code, the variable is in the object, and there are as many instances as there are objects.
If the object is a bean, the number of them depends on the object's scope: if application, one; if session, one per session; if view, one per view; etc.
If it's static member initialization code, it shouldn't be.
How is it possible, is it 2 different threads?
See above.
Who is managing this threads, web container?
Yes, and it is also managing bean instances.
If so, how web container is doing it, is it wrapping application code with threadLocal?
No. See above.
If its different threads, to maintain a global object (say a counter for the admins visit counts), "static" won't suffice... it needs to be "volatile" instead, correct?
No. You can maintain it as an instance member of an application-scoped bean.
You should avoid statics completely in a web-app, apart from constants and caches, which you should also avoid.
Are several factors that influence to answer your questions, the j2ee has own specification that manufacturers must follow, and others, they should simply implement as they wish. Is to give the performance they want, or how they should act in certain moments. A Jboss is certainly different from Apache Tomcat performance issues, which makes it hard to answer your first question. Then answer: "It depends on which vendor you are talking. Specifically what Container?"
It also depends if you implement Enterprise JavaBeans in your code because then probably several Beans (objects) will be started (depending on the container) and each request from a client he might share these Beans or create new ones to account for the competition.
Answering their fourth question, the best method would be a counter through a Singleton Session Bean (EJB implementation), in my opinion. But you could do through a static class, in which all other objects can share, but would have to resolve the competition between objects. EJB resolves this competition for you without you having to waste time with it. is for this and many other things the solution of the EJB
I think if you do not implement EJB, and make a very simple code, for each request that a customer does, an object will be created and destroyed (not really, because its depends the JVM to destroy, garbage colletction, but its inaccessible to you) after sending the response to the client container. But again, depends on how you program, of which container ... I hope I have helped you in your inquiry.
I suggest reading the J2EE specification:
JSR-000342 EE 7 Specification
And a good book to read about EJB's: Enterprise JavaBeans 3.1, 6th Edition
By Andrew Lee Rubinger, Bill Burke
This was the answer that I was looking for. Thanks everyone who answered.
Does application server create new thread for each request from same user?
Web Container (Tomcat) spawns new thread for each request (not really, it uses thread pool for performance reasons).
For any request (doesn't matter who made it) a thread is obtained from the pool, the request is processed then the thread goes back to the pool.
I have this new mvc project where all beans are default scoped(no prototype or session).
with single application context.
i want to know
by making all beans to be default scoped are we trying to achieve the whole application to be run in single thread?
if so will that make each httprequest(from multiple or same sessions) to be queued until the previous one completes?How to avoid such scenario any advice or link would be helpful.
I am relatively new to spring and java development.
Because Spring beans are typically stateless, you can safely call them from multiple threads. That's how your application works: there is only one instance of every controller, service, DAO, etc. But your servlet container (through Spring) calls these beans from multiple threads - and it's completely thread safe.
In fact in plain servlets the situation is the same - there is only instance of each servlet and it can be accessed by infinite number of threads. As long as this servlet is stateless or properly synchronized.
Do not confuse Spring with stateless session beans in ejb that are pooled and each client gets its own instance from the pool.1
1 - In fact that's a bit dumb - since the beans are stateless by the definition, there is no point in pooling them and preventing concurrent access...
Singleton means that the there will be only one instance of each bean. Generally, such beans are processing elements that carry no state. The methods called on them are passed the context which contains the inputs to work on. Hence the method calls on such singleton beans are inherently thread-safe.
I have declared a Spring bean, which polls my email server every so and so seconds. If there is mail, it fetches it, and tries to extract any attached files in it. These files are then submitted to an Uploader which stores them safely. The uploader is also declared as a Spring bean. A third bean associates the email's sender with the file's filename and stores that in a DB.
It turned out that when a few people tried to send emails at the same time, a bunch of messy stuff happened. Records in the DB got wrong filenames. Some did not get filenames at all, etc.
I attributed the problem to the fact that beans are scoped to singleton by default. This means that a bunch of threads are probably messing up with one and the same instance at the same time. The question is how to solve this.
If I synchronize all the sensitive methods, then all threads will stack up and wait for each other, which is kind of against the whole idea of multithreading.
On the other hand, scoping the beans to "request" is going to create new instances of each of them, which is not really good either, if we speak about memory consumption, and thread scheduling
I am confused. What should I do?
Singleton-scoped beans should not hold any state - that solves the problem usually. If you only pass data as method parameters, and don't assign it to fields, you will be safe.
I agree with both #Bozho and #stivio answers.
The preferred options are to either pass store no state in a singleton scoped beans, and pass in a context object to the methods, or to use a prototype / request scoped beans that get created for every processing cycle. Synchronization can be usually avoided, by choosing one of these approaches, and you gain much more performance, while avoiding deadlocks. Just make sure you're not modifying any shared state, like static members.
There are pros and cons for each approach:
Singlton beans are act as a service-like class, which some may say are not a good Object-Oriented design.
Passing context to methods in a long chain of methods may make your code messy, if you're not careful.
Prototype beans may hold a lot of memory for longer than you intended, and may cause memory exhaustion. You need to be careful with the life cycle of these beans.
Prototype beans may make your design neater. Make sure you're not reusing beans by multiple threads though.
I tend to go with the service approach in most simple cases. You can also let these singleton beans create a processing object that can hold it's state for the computation. This is a solution that may serve you best for the more complexed scenarios.
Edit:
There are cases when you have a singleton bean depending on prototype scoped bean, and you want a new instance of the prototype bean for each method invocation. Spring supplies several solutions for that:
The first is using Method Injection, as described in the Spring reference documentation. I don't really like this approach, as it forces your class to be abstract.
The second is to use a ServiceLocatorFactoryBean, or your own factory class (which needs to be injected with the dependencies, and invoke a constructor). This approach works really well in most cases, and does not couple you to Spring.
There are cases when you also want the prototype beans to have runtime dependencies. A good friend of mine wrote a good post about this here: http://techo-ecco.com/blog/spring-prototype-scoped-beans-and-dependency-injection/.
Otherwise just declare your beans as request, don't worry about the memory consumption, the garbage collection will clear it up, as long there is enough memory it won't be a performance problem too.
Speaking abstractly: if you'e using Spring Integration, then you should build your code in terms of the messages themselves. Eg, all important state should be propagated with the messages. This makes it trivial to scale out by adding more spring Integration instances to handle the load. The only state (really) in Spring Integration is for components like the aggregator, which waits and collects messages that have a correllation. In this case, you can delegate to a backing store like MongoDB to handle the storage of these messages, and that is of course thread safe.
More generally, this is an example of a staged event driven architecture - components must statelessly (N(1) no matter how many messages) handle messages and then forward them on a channel for consumption by another component that does not know about the previous component from which the message came.
If you are encountering thread-safety issues using Spring Integration, you might be doing something a bit differently than intended and it might be worth revisiting your approach...
Singletons should be stateful and thread-safe.
If a singleton is stateless, it's a degenerate case of being stateful, and thread-safe is trivially true. But then what's the point of being singleton? Just create a new one everytime someone requests.
If an instance is stateful and not thread-safe, then it must not be singleton; each thread should exclusively have a different instance.
In a traditional n tier web app with servlets for web layer and ejbs(2.0) for biz layer, what is the rationale behind making the servlet model multi threaded and the ejb model single threaded?
i.e there is only 1 servlet instance for all requests, but for ejbs, for each request, there is a new bean instance assigned from the bean pool.
There is indeed only one instance for a specific Servlet since they are supposed to be stateless. In practice this isn't always the case, but so be it.
There are however multiple instances of Stateless session beans (SLSB), and those are pooled.
By their very definition, stateless session beans are stateless, so on the surface this seems like a paradox. The things is that while stateless session beans are stateless with respect to individual calls being made to them, they in fact very often have state.
This state is in the form of references to other resources. The JPA entity manager, which is not thread-safe, is a prime example here. During a single call to a stateless session bean, the caller must have exclusive access to this resource. When the call returns, the next caller can have exclusive access, etc.
If a single instance was used, then either all callers would have to wait on each other (which is of course killing for performance), or they would have the access this single instance concurrently. In the latter case, the bean implementor has to do manual locking of the non thread-safe resources like the entity manager which is often brittle, error-prone and in the end still causes callers to wait on each other.
So, in order to improve performance and still have the safety guarantee, multiple instances are being used.
Those instances are then being pooled and re-used instead of created fresh for each request, because finding, initializing and injecting all required dependencies of the bean can potentially be time consuming.
All of this thus automatically also means that if you inject an entity manager or other non thread-safe resource into a Servlet (which is allowed), you may run into problems. This is a small loop-hole in the Java EE architecture, which is of course easily worked around by simply making use of stateless session beans.
I think that typically servlets present thin facade to the heavy logic implemented in EJBs. Servlets should be stateless and therefore there is no reason to create more than one instance of the same servlet.
If you are using stateless beans only I think that there is no reason to have more than one instance too. But statefull EJBs have state and therefore you need instance per simultaneous request.
I hope I did not say bullshit.