Spring Request and Prototype Scope? - spring

Below are the definitions of prototype and request scope in Spring.
prototype
Scopes a single bean definition to any number of object instances.
request
Scopes a single bean definition to the lifecycle of a single HTTP request; that is each and every HTTP request will have its own
instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.
As per my understanding In case of prototype scope , some pool will be maintained by core container. It will serve the bean instance from that pool.
In case of request scope, new bean will be served for each http request. Please correct me if there is some dicrepency in understanding?
If above statements are true, then if bean is holding some state then the scope should not be defined as prototype rather it should be defined
as request. Correct?

Prototype creates a brand new instance every time you call getBean on the ApplicationContext. Whereas for Request, only one instance is created for an HttpRequest. So in a single HttpRequest, I can call getBean twice on Application and there will only ever be one bean instantiated, whereas that same bean scoped to Prototype in that same single HttpRequest would get 2 different instances.
HttpRequest scope
Mark mark1 = context.getBean("mark");
Mark mark2 = context.getBean("mark");
mark1 == mark2; //This will return true
Prototype scope
Mark mark1 = context.getBean("mark");
Mark mark2 = context.getBean("mark");
mark1 == mark2; //This will return false
Hope that clears it up for you.

You are off. Prototype is described in the docs here as
"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."
Your description of request scoped beans is accurate.
Probably just got the wires crossed vis-a-vis prototype vs singleton.

Prototype scope creates a new instance every time getBean method is invoked on the ApplicationContext. Whereas for request scope, only one instance is created for an HttpRequest.
So in an HttpRequest, if the getBean method is called twice on Application and there will be only one bean instantiated and reused, whereas the bean scoped to Prototype in that same single HttpRequest would get 2 different instances.

Related

Multiple times construction

How many times Spring is calling single Singleton constructor?
In which cases constructor can be called more than one time (for bean with the same id)?
EDIT:
HERE is an answer that user is telling that can be more than once - I need more explanation for that.
How many times Spring is calling single Singleton constructor?
Only once; The default Bean Scope is singleton.
In which cases constructor can be called more than one time (for bean with same id)?
Take a look at Bean Scopes
Scope Description
singleton
Scopes a single bean definition to a single object instance per Spring IoC container.
prototype
Scopes a single bean definition to any number of object instances.
request
Scopes a single bean definition to the lifecycle of a single HTTP request; that is each and every HTTP request will have its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.
session
Scopes a single bean definition to the lifecycle of a HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.
global session
Scopes a single bean definition to the lifecycle of a global HTTP Session. Typically only valid when used in a portlet context. Only valid in the context of a web-aware Spring ApplicationContext.
What you need is scope prototype
So add a #Scope("prototype") to your bean definition like this:
#Bean
#Scope("prototype") //add this
public MyBean myBean()
{
return new MyBean();
}

Regarding Instance in Spring mvc web application development

I am new to spring mvc web development. I have one query.
Suppose we are having different service classes. So do we have one instance of those classes per request OR only single instance of that class gets create. Actually i want to use instance variables , so with each request new instance will get created or it will be like singleton type of behavior. Hopefully i am able to explain my question.
you can have either, the default is a singleton - one instance. But this can be changed using bean scope.
obligatory link to offical docs correct chapter
(personally never needed to use anything other singleton)
If you have not defined any scope explicitly, it will be singleton by default, singleton means there will be one object per spring container, for your context, one object for all your request threads. In case of singleton scope, be cautious while using member variables, because thread safety comes into picture.
If you are modifying state of a member variable inside your singleton scoped bean, you need to write thread safe code because multiple threads are accessing your member variable and a race condition may occur.
Moreover, you can define other scopes too using #Scope at the class level(i.e above #Component) or at method level above #Bean annotations.
Generally, we keep using the default scope (i.e singleton scope), this way spring container also does not waste time in creating the new object of the bean asked for, though it would be a little overhead creating an object on each request thread.
If you want a new object on every bean injection, you can have prototype scope for that bean.

Spring - why initialization is called after setter method

Just curious.
Why bean initialization is done after setter's method? I thought initialization is best done before setter method - like doing validation to ensure it's good prior to setting the value to the instance member
Why beanPostProcessor considered a after initialization when it has a beforeInitialization method?
From my understanding, calls of setters etc is considered to be the action to setup the initial state of the bean. You cannot do any meaningful initialization without the initial state of the bean set. Just think what will happen if initialization is done before setters: (assume we are using setter injection, not ctor injection) The bean is created by calling the default ctor, and then you call the initialization, what can you initialize then? The bean is simply a blank object without dependencies properly injected. If you can do initialization in such case, such kind of initialization can be simply put in your ctor.
For BeanPostProcessor, I believe the "post" is not referring to post-initialize. It is simply for you to do post processing after the bean is created (i.e. post-creation). As it is common to do such kind of post processing in two different timing, which is before and after the bean is initialized. Hence for the two methods.
So initialization can use the values set on the bean.
Because it's a post-processor.

Difference between Stateless and Stateful session bean

I knew stateful beans maintain conversational session between different instance method call,but stateless will not.My question,assume I have a stateless bean implementation like below
import javax.ejb.Stateful;
import javax.ejb.Stateless;
import com.tata.ejb3.data.HelloEJBInterface;
#Stateless
public class ValueEJB implements ValueEJBInterface{
private int value;
#Override
public int getValue() {
return this.value;
}
#Override
public void setValue(int value) {
this.value = value;
}
}
I have my bean client(A servlet) which initiates bean invocation as below
#EJB(mappedName="E/ValueEJB /remote")
ValueEJBInterface value;
....
value.setValue(250);
System.out.println(value.getValue());//This statement prints the value 250
....
According to my understanding as my bean is stateless bean it should not displayed with value 250.
private int value; is an instant variable,if one stateless method set its value , the value will be expired on method exit.But here, I am able to get the value '250' even via my second method call. Is it a violation of stateless concept? Am I lacking something?
Difference between Stateful v Stateless bean behavior when calling different methods.
STATEFUL: When calling different methods on a Stateful Bean, different bean instances are created.
((MyStatefulBeanRemote) ctx.lookup("ejb/MyStatefulBean")).doingStatefulThing();
((MyStatefulBeanRemote) ctx.lookup("ejb/MyStatefulBean")).doingNothingStatefulThing();
***Output: Note the creation of separate objects.***
INFO: Calling doingStatefulThing...com.myeclipseide.ejb3.stateful.**MyStatefulBean#2fe395**
INFO: Calling doingNothingStatefulThing...com.myeclipseide.ejb3.stateful.**MyStatefulBean#81cfcb**
STATELESS: When calling different methods on a Stateless Bean, the beans are pooled, hence no new instances of the bean are created.
((MyStatelessBeanRemote) ctx.lookup("ejb/MyStatelessBean")).doSomething();
((MyStatelessBeanRemote) ctx.lookup("ejb/MyStatelessBean")).doNothing();
***Output: Note the reuse of he bean object.***
INFO: Doing something ...com.myeclipseide.ejb3.stateless.**MyBean#213b61**
INFO: Doing Nothing ...com.myeclipseide.ejb3.stateless.**MyBean#213b61**
Interesting question and basically you are totally right. I did some research and the general advice is to: "Expect your bean to forget everything after each method call ..." (page 81). Furthermore, according to that resource, the algorithm responsible for maintaining the state of Stateless Session Beans is container / vendor specific. So the container may choose to destroy, recreate or clear the instance after method execution.
You could create a multi threaded test and see how it behaves with multpile clients.
There is no violation of any concept. Its because the same instance of bean is picked by the container from the pool to serve other request.
Stateless beans are pooled & therefore they have performance benefit over statefull beans, also their main purpose is processing without holding any state.
Sensitive or user specific data shouldn't be stored in instance variables of stateless beans. They should be used extensively to process data without any consideration of state.
Can refer here for their life-cycle events handled by the container.

In spring batch framework, what is the difference between 'lazy-init=true' and 'scope=step'?

When I defined a 'MethodInvokingFactory' bean with 'scope=step', I got an error that the type of the bean can't be determined. It worked fine when I replaced 'scope=step' with 'lazy-init=true'. As per my knowledge, both are used for the late binding of the beans, except for that one difference. Are there any other differences between these two ways? Also, is my usage correct?
Please let me know your thoughts about this.
To answer to your question from low-level perspective:
lazy-init="true" means that bean will not be instantiated when the context is created, but will be created when it is referred e.g. by another bean. I think this is clear, also from #AravindA comment.
Scoped bean works in different manner. When context is created this bean is wrapped into additional proxy object (by default created by CGLIB), which is passed to the bean that refers it (this proxy is by default singleton, e.g. shared). So each time the method is invoked on the proxy in runtime Spring intersects the call, requests the factory to return the instance of the bean and invokes the method on that bean. The factory in its turn may lookup for "real" bean instance e.g. in HTTP request ("request" scope) or HTTP session ("session" scope) and/or create new instance if necessary. Late instantiation allows to initialize the scoped bean with "runtime" (scope) values, e.g. values from HTTP request/session which are obviously undefined when context was created. In particular "step"-scoped beans are bound to thread local (remember that steps are run in parallel for partitioning). So, scoped beans are dereferred when you call a method on them. Finally one can easily break this elegant Spring "ideology" by calling any method on scoped bean just after it is set to another bean (e.g. in the setter) :)
One thing to understand about lazy-initialization is that even though a bean
definition may be marked up as being lazy-initialized, if the lazy-initialized
bean is the dependency of a singleton bean that is not lazy-initialized, when the
ApplicationContext is eagerly pre-instantiating the singleton, it will have to
satisfy all of the singletons dependencies, one of which will be the
lazy-initialized bean!
Using a scope of Step is required in order to use late binding since the bean
cannot actually be instantiated until the Step starts, which allows the
attributes to be found. Because it is not part of the Spring container by
default, the scope must be added explicitly, either by using the batch namespace
or by including a bean definition explicitly for the StepScope (but not both):
<bean class="org.springframework.batch.core.scope.StepScope" />
Read here and here for more info
The scope="step" has nothing to do with Lazy initialization . It is use for late binding of parameters inside a "Step" .
the step scope is specifically for latebinding of job/step attributes and not really for late-binding of beans, meaning the spring bean context/factory will enhance stepscoped beans and look for attributes to set, e.g.
value="#{jobParameters[input.file.name]}

Resources