I want to understand what is use of request scoped beans in spring? I know it lives only till the request is alive. But I can't think of any practical use.
It is what it is, you get a bean scoped for the current request. That means that whenever you ask the spring context to give you a specific bean which is request scoped, you will get different instances for different requests. If you ask for the same bean twice in the same request, you'll get the same instance as you would expect.
Please note that in order to use request scoped beans in a singleton bean (the default bean scope in Spring), you will need a scoped proxy. That means, you'll need to use a singleton proxy instance in your singleton beans that will actually delegate all method invocations to the per-request scoped instances of that type.
See this answer on spring scoped proxy bean for a very nice and detailed explanation.
Related
My understanding is that a prototype-scoped Java bean class is instantiated every time it is requested, as opposed to singleton-scoped Java beans which are instantiated once when the application starts up.
My question is: how much overhead does using the prototype scope cause?
Does the Spring framework make any attempt to recycle prototype-scoped objects to reduce the overhead caused by repeated instantiation?
Is the overhead caused by prototype scoping enough to warrant efforts to make as many of my Java bean classes stateless so that I can apply singleton scope to them?
You should not think of overhead between the prototype and singleton scope, but only the way they are used. If they are stateless objects that will live throughout the life time of the application, the correct scope is singleton. Many beans exist in that scope, for example controllers, beans in a service or persistence layer. Most beans related to Spring Security framework are also stateless and live in singleton scope.
If you want to create a brand new bean for a specific processing and then discard it when it has been used, then it is a use case for the prototype scope. As I mainly used spring for Web application I seldom used prototype scoped beans, but used request scoped beans which have a close use case: they are created for a HTTP request processing. The only point of attention is that if you have to inject a prototype or request scoped bean in a singleton bean, you will have to use a proxy that allows to connect to the current prototype bean (may be in thread storage) and not a bean that would have been created when the singleton was.
Using prototype scope is the same as if you were to instantiate using 'new' except that the new object will be managed by Spring. Spring will be able to apply aspects, inject dependencies, etc.. There will also be the overhead of the proxy class created to wrap the object.
Spring will not attempt to reuse the instances.
If you do not want to create a new instance whenever you reference the bean then you should not be using a prototype. Your solution will either require independent instances, maybe due to concurrency, or it will allow for a singleton. It is unlikely that the memory used by the object will be the deciding factor for what scope you use.
I have copied a sample Spring Boot SPA. I want to understand, what happens if multiple people use the web page via the URL. Does Java create an instance of the web application per call? Memory resources are not shared, right, i.e. if there is a list object appended to, each user sees their own list?
The default scope for a spring-boot bean is a singleton. Assuming your bean is not managing state you should be fine with the default behavior:
https://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch04s04.html
4.4.1 The singleton scope
When a bean is a singleton, only one shared instance of the bean will be managed, and all requests for beans with
an id or ids matching that bean definition will result in that one
specific bean instance being returned by the Spring container.
To put it another way, when you define a bean definition and it is
scoped as a singleton, then the Spring IoC container will create
exactly one instance of the object defined by that bean definition.
This single instance will be stored in a cache of such singleton
beans, and all subsequent requests and references for that named bean
will result in the cached object being returned.
Now if you are using a bean that's stateful and want a new bean used per request, you can define the scope of that bean to be prototype:
4.4.2 The prototype scope
The non-singleton, prototype scope of bean deployment results in the creation of a new bean instance every time a
request for that specific bean is made (that is, it is injected into
another bean or it is requested via a programmatic getBean() method
call on the container). As a rule of thumb, you should use the
prototype scope for all beans that are stateful, while the singleton
scope should be used for stateless beans.
Spring resources like #Service and #Repository and #RestController are stateless singletons. Only a single instance is created to serve the application.
Your implementation of the list at scope level will determine whether or not it is shared. If you define the List in the Controller, as in your example, then every user will have access to the same list. You can use multiple browsers to see that the list is shared. Based on the example, this is fine, as getting "all" should really mean getting all.
If you wanted each user to have their own list, you would have to implement some sort of Session or back-end process to associate each individual user with their own list.
This isn't shared-nothing like PHP or Rails. Java is so slow starting up that firing up a new instance of the application for every request isn't an option.
Check out the spring-boot sample application source code, there's a main method on the SpringbootJQueryAjaxClientApplication class, like this:
public static void main(String[] args) {
SpringApplication.run(SpringBootJQueryAjaxClientApplication.class, args);
}
this is the main method like for any Java program, what happens here is it starts the self-hosted servlet container and installs the application into it, then waits for http requests.
It is one process, where every request is served by a thread, so memory is shared. Spring components like com.javasampleapproach.jqueryajax.controller.RestWebController (scoped as singleton by default) are instantiated once in the web application, and every request calls methods on the same instance.
So regarding prototype scoped bean, I know spring just crate it do life cycle process before handover it to requested bean. and then if forgot it.And also logically I can understand that since it is prototype, it will be used by per request only (yes not http request.) But why not spring container just keep reference of prototype bean just to manage complete life cycle?
A "prototype" scope behaves pretty much just like any object POJO created with the "new" operator, except for the Spring prototype will have #Autowired beans connected up. The aren't singletons, or connected to sesssion or request scope, so they are just more similar to a regular POJO.
I have a simple question for you experts
Is it possible to have both a Session-Scoped and Request-Scoped for the same bean?
For example, i have a bean myBean, can it be both Session-Scoped and Request-Scoped?
EDIT
After doing some trials, i decided to destroy the first session which is session scoped.
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("SessionBean1");
is there a way i can re-initialise it to a request scoped one?
It is possible to define a bean of the same type in two different scopes by defining it in a faces-config.xml file. This will result in two different instances when referenced through expressions like #{sessionScope.myBean}, #{requestScope.myBean}, etc.
It is possible to place the same bean instance into more than one scope programmatically using the FacesContext.
However, the presence of such beans suggests a design flaw.
You can annotate a managed bean with more than one scope. The code will compile and deploy without errors (tested with Mojarra 2.1.3 / Glassfish 3.1.1).
However, the effect will be that always the most narrow scope will be applied. So if you annotate your bean with #SessionScoped and #RequestScoped, the bean will be in request scope.
I've some session scoped state. First idea to hold it was session scoped servlets. So I bind my servlet like this
bind(Foo.class).in(ServletScopes.SESSION);
But I get an exception
javax.servlet.ServletException: Servlets must be bound as singletons. Key[type=Foo, annotation=[none]] was not bound in singleton scope.
So servlets can't have scope from ServletScopes? Whats the right way to deal with session state (yeah, of course it's better to write state less servlets/classes/applications)?
From my understanding you can bind whatever you want to the session scope, the problem is that in your example Foo seems to be an subclass of Servlet, and Servlets must be bound in Singleton scope.
To resolve this, just bind your state (called Bar) in session scope and give your Foo constructor a Provider<Bar> argument (which will be filled in by Guice) so you can access the session-scoped state from the singleton-scoped Foo Servlet.
servlets are not created by Guice, but by the servlet container. And they are singletons : only one instance is created by the servlet container to serve all the requests of all the clients.
So binding them to session scope has no sense : Guice can not create one different servlet instance per session.
A servlet should always be stateless (i.e. its state should be global to all the clients, and be accessed in a thread-safe way)