I am confused.
Spring's default bean scope is Singleton. That means that once you define a bean of your class, every time a new "message" comes in, it will be processed by the same instance of that class.
But that also means that you cannot have mutable instance variables in that singleton bean because the next call of a method of that class will see data from past calls..
Example:
Calculator is my bean (singleton)
public class Calculator {
private List<String> operations = new ArrayList<String>();
public void calculate(String op, double val) {
operations.add(op);
// do some calculations
}
public List<String> getAllOperations() {
return operations;
}
}
Here's the client (useCalc is invoked many times!):
public class CalculatorClient{
#Autowired
private Calculator calculator;
public void useCalc () {
calculator.calculate("Add",100);
calculator.calculate("Div",100);
calculator.calculate("Diff",100);
List<String> allOperations = calculator.getAllOperations();
// Do something..
}
}
So let's say CalculatorClient useCalc gets called several times with different operations..
eventually operations in Calculator will contain all of the operations ever done on that calculator.
So the question is this:
Is this Spring's limitation - not being able to effectively share information between methods within a class? And if it is so, how to share that kind of information between methods?
I know there is the prototype bean scope. Is that the only solution in this case?
BTW, prototype is not a solution here because with prototype a new class will get instantiated with every call to calculator:
calculator.calculate("Add",100); // New
calculator.calculate("Div",100); // New
calculator.calculate("Diff",100); // New
And since Singleton is the default scope - aren't developers inadvertently introduce such bugs?
A common use case for singleton beans are to inject services into other objects.
Example, to provide an object a service to connect to the database, you "autowire" a database connection bean.
You don't want to create a new instance of the database every time, so singleton beans make sense.
Usually, the object itself that uses the autowire is a singleton as well (in a web app, the Controllers are also created just once, you don't want to create a controller for every request).
aren't developers inadvertently introduce such bugs?
Since the idea is to process several requests concurrently, all of those objects are usually already coded without having common state shared using instance variables.
This is not a "limitation", but rather a default for the most common use case.
I know there is the prototype bean scope. Is that the only solution in this case?
It sounds like a good "solution" to this, in that case a new bean will be created. Note that it would not make sense to autowire a prototype bean into a singleton since in that case there will only be once instance anyway.
Another possibility more commonly used is autowiring a singleton bean that acts like a factory, then ask that factory for a new object each time you need one.
The factory can be a singleton since you don't want more than one factory, but it would then return new objects in every call to its "create" method.
So in your example, you could do something like
#Autowired
private CalculatorFactory calcFactory;
public void useCalc () {
calculator = calcFactory.createCalculator();
calculator.calculate("Add",100);
calculator.calculate("Div",100);
calculator.calculate("Diff",100);
List<String> allOperations = calculator.getAllOperations();
// Do something..
}
}
There's a lot of conflation going on here. Let me try to unravel the premises.
The whole point of dependency injection is to make it so that you don't have multiple instances of a critical application service, which would lead to things getting out of sync or result in erratic behavior (e.g. multiple database connections, multiple access points to a JMS queue, multiple ways to query a database, etc).
It is not a mandate to make everything injectable.
If something is not inherently reusable, or you would not gain anything from registering it in the component scan, then there is no reason to make that thing either a bean or a component.
It is fairly reasonable to assume that beans shouldn't store state, but that doesn't mean that something else couldn't store that state on its behalf. For instance, you could put those operations into some other backing store as opposed to in-memory, and you'd still be able to keep the state of operations you've done.
The big thing that I'm seeing is that you've kind of implemented your Calculator class half-thinking that it was a bean, and half-thinking that it was newed up somewhere. By having that list in your class, you're subconsciously forcing yourself to hold onto the state in any instance created, which violated the inversion of control principle - you don't control the lifecycle of the object.
To get around this...you have a few options available.
Change how you're storing the state of your operations. Put it into a SQLite database or a file or somewhere that isn't dependent on an instance maintaining it.
Inject your own. You can create a bean that is of type List<String>, and require your Calculator to inject it when it's needed.
Don't create a bean. You can new this and Spring isn't really going to fuss at you. It'd make it harder to test, though.
The first two approaches abstract away the notion of storing the data from an operation and reading the data from the operations. You can either read from the injected operations bean or from the SQLite database or from the flat file to get the result of operations that you want.
Related
I have the following design. When a client makes a request to the server, the server creates a state that holds all sorts of info. There are various stateless and stateful beans which need to read and write to this state. Refer to this unprofessional diagram:
The ComputationCycle class is where the processing starts and works by phases. During each phase it calls upon other Manager classes (which behave like utility classes) to help in the computation (diagram shows only for 1 phase). The state is being read and written to both from the CC class and the managers, both are stateless.
State holds Employee, Department and Car classes (in some irrelevant data structure) which are stateful. These classes can also call the Manager classes. This is done by a simple #Inject Manager1. The same way CC uses managers.
My problem is how to access the stateful state (and its contained classes) from the stateless classes (and from the Car, Department and Employee classes too, although I think solving one will solve the other). I can't inject a stateful bean into a stateless bean. So after the client makes a request and the computation cycle starts, how do I access the state related to this request?
One solution is to pass the state to every method in the stateless classes, but this is really cumbersome and bloaty because all methods will have an "idiotic" State argument everywhere.
How can I make this design work the way I want it to?
I can't inject a stateful bean into a stateless bean.
You can absolutely inject dependencies this way.
If the stateful bean is #RequestScoped, any call into the stateless bean on that thread that hits a CDI injected contextual reference (iow proxy) will find its way to the right instance of the stateful bean.
As long as you use CDI, you don't need to trouble yourself with trying to stash things away in your own threadlocals.
Buyer beware, ThreadLocal will possibly do what you're wanting, along with a static accessor. However, this class is prone to causing memory leaks if you are not extremely careful to remove each entry at the end of the request. In addition, you seem to be using EJB; I assume they are all in the same JRE. I use ThreadLocal quite a bit in similar situations, and I've had no problems. I use SerletContextListener's to null the static reference to the ThreadLocal when the context shuts down, although that has been problematic on some older Web app servers, so I make sure the ThreadLocal exists before attempting to use it.
EJB can "talk" to each other across servers. It sounds local all your EJB are running in the same context.
Create a class that holds your state.
Extend ThreadLocal--you can do this anonymously--and override initialValue() to return a new instance of your class.
Create a utility class to hold the ThreadLocal as a static field. Don't make it final Create static fetch and remove methods that call ThreadLocal.get() and remove(). Create a static destroy() method that is called when your context shuts down--see ServletContextListener.
I'm a bit confused about my new class type I've written.
My class would be used to serve question and options pulled from database for about four thousands concurrent users. (Because exam will start at the same time for all)
Now what class type should I use for making it work faster.
Would it be good if I make it static?
public static List<Questions> getQuestions(String qType){
List<Questions> objListExamsExt = new ArrayList<Questions>();
....
....
....
while (cursor.next()) {
Questions objExamQuestion = new Questions();
objExamQuestion.setQuestion_id(cursor.getString("question_id"));
....
....
....
objListExamsExt.add(objExamQuestion);
}
return objListExamsExt;
}
A case where a static class might be a good idea is when you want to collect related pieces of functionality, but you don't need to have any internal state in any object.
Normally you can create a static Utils class containing a whole bunch of related functions that are accessed outside the context of any specific object instance
A singleton allows a class for which there is just one, persistent instance across the lifetime of an application.A singleton class might be useful if you have some kind of shared resource, such as a database, an in-memory cache, or maybe some specialized piece of hardware like a robotic arm. Many parts of your program might want to use this resource and you might want to have all access to the resource go through a single point. A singleton isn't always the only way to handle these situations, but it's one of the few places I think a singleton might be a good choice.
In your case if getQuestions() is used in multiple places in your application then you can group it together inside a static Utils Class.
What is the difference, if I autowire a class and provide value and instantiate an object of class and provide some value?
For example-
#Autowired
private UserService userService;
userService.findUser(userName, password);
And
User user = new user();
userService.findUser(user.getuserName(),user.getpassword());
What is the difference in Autowiring and sending the data and instantiating the object and sending the data to some service class?
I'm trying to clarify the concepts in spring.
When you use #Autowired you are leaving it up to the Spring framework to find and instantiate the userService. This is usually controlled through some configuration file or some other configuration, which allows you to change the behaviour of your application without changing the code itself.
On the other hand, when you instantiate the object yourself, you are specifying which object you are after and what type of class you want. This could leave you with less ambiguous code since you know what type of object is being initialized, but to make a change in your application's behaviour you would need to change your code.
In essence, the first option is less coupled than the second option, which is usually the recommended way of building things.
Your example doesn't make a lot of sense; this User class, which looks like some plain data object, isn't adding anything to the second snippet.
The idea of "autowiring" is that some class, like maybe a Web controller, will need a UserService in order to get its work done. When Spring autowires the UserService, it goes into the context and finds a matching object and provides it to the class that needs it. This is technically separate from creating the object.
That said, the best practice is to use constructor injection--simply declare the other objects you need as constructor parameters and annotate the constructor with #Autowired (or #Inject). Spring will know to look up all the dependencies you need and call the constructor with them. This means that it's also very simple to provide mocks of those objects for testing or development.
Well, the main difference is that in case u use #Autowired the object is also created, however, it's created by container and container decide when to do that.
I want to give you a simple example:
You have four classes 1,2,3 and 4. Three of them (1,2,3) uses the 4th. So, if you use new(), it`s hard to decide where to create object(in class 1, or 2, or 3, or even in each of them) of 4th class. Moreover, later you can delete class with object initialization and other 2 classes won't work (in case you created one object). Autowired annotation injects the object but you don't initialize object in class, so no problems appear
This is like the simplest answer.
the above answers are good i would like to tell a major difference between them .the purpose of autowiring is to avoid the dependencies between the class
if you are creating objects with new making a change to one class will effect all the classes.
I am learning Spring and have found the book Spring in Practice to be an awesome source. I don't understand Spring bean singleton scopes completely however. And what I read in the section of bean scopes has confused me a bit.
Here is a excerpt from that section:
As you request singleton beans from the container, Spring will create
instances and cache them if they haven’t been created; otherwise,
Spring will return already-existing instances from its cache.
Therefore, singleton beans in Spring often don’t maintain state
because they’re usually shared among multiple threads (such as in
servlet environments). For example, singleton services often have
references to singleton DAOs, and the DAOs might have references to
Hibernate SessionFactorys, which are threadsafe.
Now I don't know much about multithreading in Java so please pardon my ignorance. In the above excerpt where it says "Therefore, singleton beans in Spring often don’t maintain state because they’re usually shared among multiple threads"
1). What does this mean for domain objects? Can I have a domain object called User defined as a singleton scope in the spring context? What would happen?
2). I notice that mostly datasources and large configurations are usually in the spring xml file. I have a feeling my questions relating to state and beans defaulting to singletons is related to wiring only big parts of an application.
Can someone clarify this topic for me? An example would be really helpful.
Thank you in advance.
A Java class is a description of state and behavior. An instance of that class is a holder of state that can exhibit behavior. Therefore, this class
public class Foo {
private String bar;
public Foo(String bar) {this.bar = bar;}
public void print() {System.out.println(bar);}
public void setBar(String bar) {this.bar = bar;}
}
describes a data structure which has a String as state and print() and setBar(String) methods as behavior. If you create an instance
new Foo("the state");
You now have an actual data structure that holds the String data (or state) "the state" and that can display that data by invoking the print() method or change it with setBar(String).
The problem with the class above is that it is mutable, ie. its state can change. If multiple threads are operating on it, you might see unexpected behavior. For example, one thread changes bar's value before another thread has the chance to print() out its previous value.
What does this mean for domain objects? Can I have a domain object
called User defined as a singleton scope in the spring context? What
would happen?
This means the exact same thing for domain objects as it does for service or presentation objects. You can very much have a domain object of type User defined as singleton scope in the Spring context. If you want to is a different question. Do you want your application to only ever have access to that one User instance? No, then don't make it singleton. Yes, then make it singleton. This only applies if Spring is actually managing the instances for you.
More clarifications:
It's important to understand what a Singleton is. Wikipedia says
restricts the Instantiation of a class to one object
If we are taking about restricted in regards to a JVM, a Singleton could be implemented as described here. If we are talking about restricted in regards to a Spring ApplicationContext, then we are talking about a Spring managed singleton scope bean (read the chapter carefully). For example
<bean id="customBean" class="org.mine.CustomBean" />
which is retrieved like
(CustomBean) context.getBean("customBean");
// or
context.getBean(CustomBean.class);
If we are always retrieving the instance from Spring's ApplicationContext, we are effectively only ever instantiating the class once.
So if that variable is being accessed by different parts of the
application, the state of the object can be changed by that variable
by executing for instance the setter methods on that variable. But
that seems like a singleton to me.
A web application is multi-threaded. If each thread is accessing the singleton bean and mutating it, you might get lost updates. These are typically not desired since you cannot predict them and therefore are hard to test.
That variable can be used to keep changing the same data structure
throughout different parts of the application. So how is the Foo
object not a singleton?
As stated earlier, Singleton is a pattern that describes how an instance is unique in regards to some context. Simply doing
new Foo("the state");
doesn't make that object a singleton. It's how you use it that makes it a singleton.
Well, if multiple threads change the same object at the same time, they'll interfere with each other. Most spring applications harness the power of multiple threads.
A singleton scoped bean corresponds to a single object (hence the name). Everyone asking for that bean will get the same object.
Therefore, you should not change that shared object.
What does this mean for domain objects? Can I have a domain object called User defined as a singleton scope in the spring context? What would happen?
Sure you could declare a bean of type user, but - as we learned above - everyone asking for that bean will get the same user object. Is this really what you want? For instance, if the bean is intended to represent the logged in user, this design would imply that only a single user can log in ...
On the other hand, if the bean merely holds configuration data that equally applies to all users, it would be quite reasonable to for the threads to share the same object (of course, if they change it, synchronization is required to prevent interference).
I notice that mostly datasources and large configurations are usually in the spring xml file.
That is indeed the typical use. Data that should be different for each thread is typically kept in local variables (or objects reachable from there). Because local variables are different for each method invocation, interference by other threads is not possible.
You can also use spring to manage short lived objects by declaring beans with a short-lived scope (such as session or request scope in a servlet environment) - though in that case, you'll have to take care that different threads don't access the state of the same object at the same time. With request scope, that's usually easy because requests are usually processed by a single thread. With session scope, you'll actually have to synchronize access.
My application requires access to certain Objects throughout the application. These objects are populated through the DB.
I would like to populate the objects on server startup , and then in the application on a need -to -do basis.
What is the best pattern to implement this, i have read about the Registry pattern, but not sure that is exactly what i want.
I am also using Spring 3.x in my application , is there something in Spring that can help me?
Since you say you are using Spring. The best solution is to use FactoryBean. What this class allows you to do is create a bean of whatever type you like and return it to the Spring context. Spring will manage this bean and expose it to other beans by making it a singleton. An example:
public class MyObjectFooFactoryBean extends SimpleJdbcDaoSupport implements FactoryBean<ObjectFoo> {
private String query;
#Override
public String getObject() throws Exception {
return an ObjectFoo here using SimpleJdbSupport (Because I also extended SimpleJdbcDaoSupport)
}
#Override
public Class<?> getObjectType() {
return ObjectFoo.class;
}
#Override
public boolean isSingleton() {
return true;
}
}
Above does two things. 1) Extends SimpleJdbcSupport which allows you to have access to the databse, and 2) Implements FactoryBean which returns the object to Spring's context. After this is done, you can #Autowire it or use it in the xml file.
Are you sure your application really requires that?
Global objects are artifacts from the past of programming, they shouldn't exist anymore in a proper object-oriented environment, and are usually considered an anti-pattern.
Surely you don't need to access these objects everywhere. Why don't you just inject them in the classes that need them? If you use Spring, that's even easier, only have to declare the dependency in the context.
If there are many of these objects that you need, you could wrap them all in one holder class, that you inject as needed.
When I use global objects I usually wrap each object in a singleton pattern. It's the simplest solution, and you can even lazy load it only when needed.
In some cases this is a very valid pattern. For example in any iphone app you have a singleton Application object which is accessible globally through a public static method
This can get a bit hairy if your application is deployed in multiple servers (each with its own VM, thus having singletons as static fields will get messy, and having context-based attributes won't work unless the servers are set to replicate and that's unreliable as well). I'd recommend using a database memory table instead, or some other sort of server-independant memory cache. ( http://memcached.org/ for instance)
What about defining a global object to store these information? You can control access to this object. If you want to monitor this object's state, you can use observer patterns.