Regarding Instance in Spring mvc web application development - spring

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.

Related

how spring singleton scope for DAO class works internally

I went through some blogs and spring docs about the Spring singleton scope along with almost all spring singleton and DAO related question in stackoverflow.
I still do not have clear understanding of how the same object is injected to all the class which depend on it. I have learnt that the DAO needs to be stateless.
If the following DAO (sample dao having instance variable mainly to clear confusion) class is defined with default singleton scope and the same object is injected everytime, then there might be scenarios where department is null and therefore it won't set anything for department value instead use whatever the previous object value was.
public class UserDAO{
int userId;
Spring userDepartment;
// getter setter methods for userId and userDepartment
public boolean addUserToUserDetailsTable(int uId,
String name, String address, String department){
// set userId
userId = uId;
if(department!=null)
userDepartment = department;
// write code to add user to user table
// TO DO
// save user department data
addUserToUserDepartmentTable(userId, userDepartment);
}
public void addUserToUserDepartmentTable(int uId,
String department){
/* Code to save department data */
}
}
So if instead of using DI, if I manually call the DAO using new operator this problem won't be there.
new UserDAO().addUserToUserDetailsTable(id, "abc", null);
the above confusion generates following questions
how is spring creating and injecting singelton beans, is it really one and only one object which gets injected to all calling classes. If this is true then how the previous object values from above DAO class is reset.
won't the instance variable hold their values here userId, userDepartment if the same object is called from multiple class ?? Does stateless means the class cannot have instance variable.
does spring internally uses new object() to inject the beans.
or it creates an object of DAO class and makes multiple clones of the object, which i think is not possible because the DAO class is not implementing clonnable.
Please help me clearing the above confusion.
how is spring creating and injecting singelton beans, is it really one and only one object which gets injected to all calling classes.
Yes, it's injecting a single instance, always the same, of the DAO class. That's the definition of singleton: a single instance is created.
If this is true then how the previous object values from above DAO class is reset.
It's not reset.
won't the instance variable hold their values here userId, userDepartment if the same object is called from multiple class ??
Yes, the unique instance will hold the userId and department, since these are fields of the instance. You might run into problems trying to read and write these values, though, since they constitute shared mutable state, which is accessed concurrently from multiple threads without any synchronization.
Does stateless means the class cannot have instance variable.
In the strict sense, yes. But a DAO doesn't need to be stateless. It needs to be thread-safe, since the same instance is accessed from multiple threads concurrently. The best way to achieve that is to avoid having any state (so no instance variable). But this is hard to achieve for a DAO, which normally needs to have access to an injected DataSource, of JdbcTemplate, or EntityManager, or whatever. Since, however, these instance variables are normally injected by Spring during startup, before the DAO starts being used by multiple threads, and never written to during the lifetime of the application, that is thread-safe. Your code, however, has state, and the state is modified during the lifetime of the application, which makes it not safe.
does spring internally uses new object() to inject the beans.
It depends how the DAO bean is declared. It can be declared using JavaConfig, using a #Bean method calling the constructor. Most of the time, reflection is used to call the constructor. So there is no new MyDAO() in the code anywhere, but the constructor is still called (only once since it's a singleton), because that's the only way to create an instance of an object from scratch.
or it creates an object of DAO class and makes multiple clones of the object, which i think is not possible because the DAO class is not implementing clonnable.
That wouldn't be a singleton if it did that.
Singleton scope beans in Spring means one instance per container and the bean has to be stateless or else you will run into issues in cases of multi-threaded scenarios.
how is spring creating and injecting singelton beans, is it really
one and only one object which gets injected to all calling classes.
Spring creates once instance at startup and passes the same reference to all the calling objects which has requested for the same via Dependency injection.
If this is true then how the previous object values from above DAO
class is reset.
If your bean is stateless there would be no value held by the object, as most of the variable would be method local and not tied to the Instance object (DAO class in this case). However in your case since you have member variable tied to a class
all the classes which acquire this DAO bean would see the same value set to the member variable and this data will be be corrupted and is not recommended.
won't the instance variable hold their values here userId,
userDepartment if the same object is called from multiple class ??
Does stateless means the class cannot have instance variable.
Yes this the exact definition of bean being stateless. As explained above.
does spring internally uses new object() to inject the beans. or it
creates an object of DAO class and makes multiple clones of the
object, which i think is not possible because the DAO class is not
implementing clonnable.
If you have not defined the bean scope, by default spring would assume it is Singleton. The understanding of singleton scope and singleton pattern is different. Spring mimics singleton pattern by providing only instance but this does not stop you from creating new instance (using say new operator).
Your Singleton is not stateless. Userid and Department define the 'state'.
Spring creates one instance using reflection 'newInstance' or a producer function in your configuration.
This one instance is then provided to all objects requesting the DAO.
Your considerations are all valid but not resolved by spring: Since your DAO has a state, it is not properly implemented and results are undefined.
Answer to question 1: It is not reset. Spring won't handle state for you!
Basically (Q2) you are on a dangerous path if you use instance variables in stateless beans. The instance vars need to be stateless themselves, like other DAO singletons.
UPDATE: I want to elaborate on this. The singleton can have a state, but the state is shared between all users of the DAO. This does not strictly require your DAO to be thread safe: If you do not use threads, there is no concurrent use - but the state of a singleton is a shared state: All users of the singleton have the same. If you have two functions like so:
#Component
public class A {
#Autowired
DaoObject singleton;
#Autowired
B another;
public void aFunctionA() {
singleton.userId = "Foo";
System.out.printf("UserId: %s%n", singleton.userId); // prints Foo
another.aFunctionB();
System.out.printf("UserId: %s%n", singleton.userId); // prints Serviceuser
}
}
#Service
public class B {
#Autowired
DaoObject singleton;
public void aFunctionB() {
singleton.userId = "Serviceuser";
}
}
The state of the singleton singleton is shared between all users of the class. If one class changes the state, all other users have to cope with that.
If you are using threads, this adds extra complexity on stateful singletons, as your modifications to state must be thread safe.
It is common practice to keep a singleton immutable after initialization.
On your 4th question: Spring will not clone a Singleton, as described above.

UnderStanding of #Controller #Service #Repository

I have a doubt regarding dependency injection,Suppose my controller ,service,dao all are singleton so usually when we create the controller we inject the service as a instance variable of that class, but according to the singleton pattern if our controller is stateless then only we would not face any concurrency issue but here We are declaring the service dependency so it should not be stateless so we have to take care of synchronization?
Please clear this doubt as I am beginner so I hope its natural to have this doubt in mind,I don't know if I am thinking totally wrong.Please help.
All beans in Spring are Singleton by default. This includes any #Controller, #Service, #Repository and others, as well as any xml defined bean.
You could read this and this
From Java basic variable tutorial:
Local Variables Similar to how an object stores its state in fields, a
method will often store its temporary state in local variables. The
syntax for declaring a local variable is similar to declaring a field
(for example, int count = 0;). There is no special keyword designating
a variable as local; that determination comes entirely from the
location in which the variable is declared — which is between the
opening and closing braces of a method. As such, local variables are
only visible to the methods in which they are declared; they are not
accessible from the rest of the class.
If your service and controller are stateless, it's ok to inject one to another.
You should not declare any variable which keeps a state in these classes. final variables are ok.
If all operations are defined in methods and they don't use any variables of the classes, dependency injection that you're doing is totally safe.
That's why you need to use #Autowired when you declare a dependent service. Effectively handing the initialization process to the Spring framework instead of instantiating it yourself. Since Spring only has stateless beans, you're injecting one stateless singleton to another stateless singleton, so there's no need to manage thread manually.

getting bean id of target class in advice

I have a few classes that interact with databases (more than one). Some classes are reused so for example "obs.table1" is used to interact with table1 in database "obs" while "ref.table1" is used to interact with table1 in database "ref". These databases are at different URLs and each gets its own connection pool, etc... obs.table1 and ref.table1 are both instances of MyTable1Class, defined in beans file.
I have a pointcut that intercepts calls to methods annotated with #Transactional or with a custom annotation #MyTablesAnnotation and have it set so those calls will all get routed into a #Around advice.
This all works and the flow through the advice is correct.
What I am trying to add is reporting on what is going on in there. Currently I can tell where in there I am, but I can't tell if it was obs.table1 or ref.table1 object that got me there.
Is there a way to extract the bean id of the object on whose method the advice was invoked on?
ProceedingJoinPoint that is passed to the method the only thing I do with it is call a .proceed on it and the rest is just various checks and catches. I see that I can get either the target class or proxy class out of it, but... not sure how to go from there to knowing what the bean id was.
Is it possible?
Firstly it is not recommended to depend on bean id as it creates tight coupling with framework.
To quote from docs Note that it is not usually recommended that an object depend on its bean name, as this represents a potentially brittle dependence on external configuration, as well as a possibly unnecessary dependence on a Spring API.
Now to answer your question yes it is possible to fetch the name of bean via org.springframework.beans.factory.BeanNameAware.
The class for which you require the bean name should implement it and spring will auto-magically inject the name of the bean. However there is a gotcha which you should be aware and is mentioned in docs here

Is Singleton an Anti-pattern?

Is Singleton an anti-pattern? If yes, then Dependency Injection in Spring also Anti-pattern (because Spring promotes Singleton bean which is default)?
There's an important difference between hard-coding a singleton and using Spring to create a singleton bean: the latter is just configuration.
As such Spring doesn't prevent testability: it's a single use-case where a bean is used as a singleton. You can easily use the same spring by manually instantiating it in a test, or replacing it with a mocked implementation of the same interface.
If you code a class as a singleton then you can't easily replace it, without rewriting it. Testing is just a single example where you might want to replace it. If you realize that you'll need two different instances of that bean, then you're stuck with a hard-coded singleton as well.
The Singleton pattern is no anti-pattern, it is a patter to restrict the number of instances
for an object.
But abuse the singleton to provide global instances is a anti-pattern.
For the spring part of your question see Joachim Sauer answer.

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