i'm new to Spring starting to learn new concepts , and i found topic speaking about bean Scopes :
- Singleton : returns the same instance every time.
- Prototype : returns new instance of the object per every request.
my question is : how is this helpful for me what is the difference between the same instance , and new instance of the object , or why the prototype scope exists !
Same instance would mean any call (from anywhere) to getBean() from ApplicationContext or BeanFactory will land you with the same instance, i.e. constructor is called just once when Spring is being initialized (per Spring container).
However, there are scenarios when you would want different object instances to work with.
For example, if you have a Point object as a member variable in a Triangle class, in case of Singleton, when the Triangle class is being instantiated, the Point object also is instantiated as it is dependent.
If you require a different instance of Point to work with elsewhere, then you will need to define the Point as a prototype, else it carries the same state.
Googling would surely help you find answers and examples demonstrating the use case.
Hope this helps.
In case if the same instance is injected everywhere as Singleton, you can use it's shared state for containing any kind of data. In case if new instance is created any time bean is being injected - it's state is not shared. By default all beans are Singletons. Prototype scope stands for cases when bean's inner data should be unique for each place you inject bean into.
Example: you have the bean which represents REST client. Different parts of application use different REST services, each requires some specific request headers - for security purposes, for example. You can inject the same REST client in all these beans to have it's own REST client bean with some specific headers. At the same time you can configure client's politics in common for the whole application - request timeouts, etc.
See also: When to use Spring prototype scope?
It helps in designing a software, refer java design patterns you fill find much useful information, In case of singleton you will be able to create only object, it will helps cases like 1.saving time in creating a very complex object (we can reuse the same object) 2.Some times we need to use the same object throughout the application E.g if you want count the total number of active users in the application, you can use singleton object to store it, because there will be only one object so you can easily update and retrieve data. In case of Prototype it will always give you different object, it is necessary in some cases like some access token, you should always get the new /valid token to proceed further, so prototype pattern /Bean is useful.
My understanding for Singleton is more likely used in the situation like return single Utility instance.
//SomeUtil is Singleton
var util = SomeUtil.getInstance();
print(util.doTask1());
print(util.doTask2());
If another thread goes into these code, SomeUtil.getInstance() just return the SomeUtil instance other than creating a new one (which might cost much to create a new one).
As to Prototype, I just found this situation using Prototype:
Lets understand this pattern using an example. I am creating an entertainment application that will require instances of Movie,
Album and Show classes very frequently. I do not want to create their instances everytime as it is costly.
So, I will create their prototype instances, and everytime when i will need a new instance,
I will just clone the prototype.
Example code locates https://github.com/keenkit/DesignPattern/tree/master/src/PrototypePattern
Related
I don't quite know how to explain the situation, I will try to be as clear as possible.
I am currently writing a web-application, using Spring to manage the beans. Obviously, more than one people will use this application. Each user has a set of data related to himself. My problem comes with some poor design I introduced when I just entered the development field. Here is the case:
#Component
public class ServiceClass implements IService {
#Autowired
private Dependency firstDependency;
#Autowired
private UsefulObject secondDependency;
private DataSet dataSet; // THIS LINE IS IMPORTANT
public void entryPoint(String arg1, int arg2, Structure arg3) {
/* Query data from a database specific from the project (not SQL
oriented. I absolutely need this information to keep going. */
dataSet = gatherDataSet(String ar1);
/* Treat the data */
subMethodOne(arg1);
subMethodTwo(arg2);
subMethodThree(arg3);
}
private subMethodOne(String arg1) {
// Do some things with arg1, whatever
subSubMethod(arg1);
}
private subSubMethod(String arg1) {
/* Use the DataSet previously gathered */
dataSet.whateverDoing();
}
... // Functions calling sub-methods, using the DataSet;
As every user would have a different dataSet, I thought it would be good to call it at the beginning of every call to my service. In the same way, as is it used very deep in the call hierarchy, I thought it would be a good idea to store it as an attribute.
The problem I encounter is that, when two users are going through this service nearly simultaneously, I have a cross-data issue. The following happens:
First user comes in, calls gatherDataSet.
Second user comes in, calls gatherDataSet. First user is still treating !
First user still uses the dataSet object, which was overrid by Second user.
Basically, the data first user makes use of become false, because he uses data from the second user, which came in short after him.
My questions are the following:
Are there design pattern / methods to avoid this kind of behavior ?
Can you configure Spring so that he uses two instances fo two users (and so on), to avoid this kinf od problems ?
Bonus: (Kind of unrelated) How to implement a very large data mapper ?
Object member variables (fields) are stored on the heap along with the object. Therefore, if two threads call a method on the same object instance and this method updates object member variables, the method is not thread safe.
However, If a resource is created, used and disposed within the control of the same thread, and never escapes the control of this thread, the use of that resource is thread safe.
With this in mind, change your design. https://books.google.co.in/books?isbn=0132702258 is a must read book for coming up with good java based software design
More stackoverflow links: Why are local variables thread safe in Java , Instance methods and thread-safety of instance variables
Spring promotes singleton pattern and (it is the default bean scope). Spring configuration for having two service class objects for two different users is called prototype bean scoping, but should be avoided as far as possible.
Consider the usage of in-memory Map or an external no-sql datastore or an external relational database
Can you configure Spring so that he uses two instances fo two users (and so on), to avoid this kinf od problems ?
You already mentioned correctly, that the design decisions you took are flawed. But to answer your specific question, which should get your use-case to work correctly, but at a impact to performance cost:
You can set spring beans to various scopes (relevant for your usecase: prototype / request or session), which will modify when spring beans get instanced. The default behaviour is one bean per spring container (singleton), hence the concurrency issues. See https://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch04s04.html
The easiest solution is simply to not store the dataset in a class field.
Instead, store the dataset in a local variable and pass it as an argument to other functions, this way there will not be any concurrency problems, as each call stack will have it's own instance.
Example:
public void entryPoint(String arg1, int arg2, Structure arg3) {
// Store the dataset in a local variable, avoiding concurrency problems
Dataset dataSet = gatherDataSet(String ar1);
// Treat the data passing dataset as an argument
subMethodOne(arg1, dataset);
subMethodTwo(arg2, dataset);
subMethodThree(arg3, dataset);
}
Use synchronized modifier for it.
As "Synchronization plays a key role in applications where multiple threads tend to share the same resources, especially if these resources must keep some kind of sensitive state where manipulations done by multiple threads at the same time could lead the resource to become in an inconsistent state."
public void someMethod() {
synchronized (object) {
// A thread that is executing this code section
// has acquired object intrinsic lock.
// Only a single thread may execute this
// code section at a given time.
}
}
I found several resources to help me with this issue, but I can't seem to mix all the ingredients in order to suit my needs.
I want to "lock" a Cat (or even several) from being petted by other users, if a petting of it (or them) is already in progress. I also want to provide a feedback to the caller, telling him who called the API before him.
#Local
#Singleton // or #Stateful?
public class CatPetterBean_Local implements CatBean_Facade
{
/**
* Key - The ID of the Cat
*/
final private ConcurrentHashMap<Integer, User> pettingState = new ConcurrentHashMap<>();
#TransactionAttribute(TransactionAttributeType.REQUIRED)
#Override
public GzipROWithMsg<Object> pet(final ImmutableSet<Integer> catIds)
{
checkIfTheyAreBeingPetted_AndThrowRuntimeExec(catIds);
<...>
// After petting, they will be saved by the caller bean (e.g. CatPetterBeanImpl)
}
<...>
}
Petting takes a while
Cats retain a state in the DB: ALREADY_PETTED and NOT_PETTED. Once it is already pat, it cannot be petted again. I even thought of loading the Cat from the DB and checking its state on-the-fly, but I think it's more network traffic that way.
How can I take advantage of notions like synchronized keywords, #Lock annotations
No, I am not using Spring
No, This isn't a webapp
Yes, I do lack EE knowledge. I'm asking this question in a process of fast learning.
EJB Singletons have under the hood a locking mechanism, by default, all bean methods are serialized via write locks.
The default concurrency model on EJB Singletons is: #ConcurrencyManagement(ConcurrencyManagementType.CONTAINER), this is the default, no need to annotate the singleton with this. When Container Concurrency Management is in play as I said before every method is write locked. If you want finer control over singleton methods you can annotate them with #Lock(LockType.READ) which means that the method can be accessed concurrently while no one holds a write lock on the bean, or #Lock(LockType.WRITE) giving exclusive access to the current thread.
Alternatively, you can use Bean concurrency management. In this case, you should annotate your singleton class with: #ConcurrencyManagement(ConcurrencyManagementType.BEAN).
In this case, you use synchronized and other Java concurrency goodies. For most of my needs Container Managed concurrency was more than enough.
Another remark to the above code fragment is that #Local doesn't seem appropriate, my guess is that CatBean_Facade should be annotated with #Local.
Using domain driven design, where are simple value objects/entities instantiated?
For example, if i needed to create a simple value object in a service class, would I just call the new operator on the value object's class, coupling this to the service class?
Can the new operator be called in a service class according to domain driven design?
These value objects can't be injected through a DI container and they don't warrant the use of a factory because of their simplicity.
What's wrong with instantiating them directly from their constructor?
Usually you only want factories when the instantiation process is complex or when you want to relieve the client from choosing a concrete class.
However, since the ubiquitous language is crucial in DDD it's quite common that an aggregate will have factory methods to create other aggregates to which they relates.
For example, rather than spawning project tasks out of thin air like below:
var task = new Task(projectId, ...);
You could do:
var task = project.addTask(...);
That would express the "tasks can be added to projects" use case better at the cost of having to load a Project aggregate.
I want to know when should I exactly use the prototype scope in Spring? I have understood that singleton returns the same object instance if the bean is requested for.
Then why should we consider prototype?
Explanations with examples would help a lot to understand the need for it.
To be clear simple definitions:
Prototype scope = A new object is created each time it is injected/looked up. It will use new SomeBean() each time.
Singleton scope = The same object is returned each time it is injected/looked up. Here it will instantiate one instance of SomeBean and then return it each time.
Prototype bean is created at the time of usage. So when you would like to have stateful beans there is a strong need sometimes to have prototypes scope or when you don't want to cache any values in beans. Prototype bean can be associated with one session or some call.
Example:
A data access object (DAO) is not typically configured as a prototype, because a typical DAO does not hold any conversational state; it was just easier for this author to reuse the core of the singleton diagram.
There are some interesting use cases by using scope prototype you will build a better and reliable application design/architecture, for example, a real-time system.
Imagine that you must build a real-time system for vehicle tracking, and you will have 2.000.000 cars sharing information every 5 seconds,
In the server side, you will work with two or more distinct group of configurations, one for Cars and another one for Trucks.
Based on this simple example, if you design your application to work with distinct configuration groups in memory through the prototype pattern you will achieve a better performance.
So, in this case, whenever the server receives a new message from a Truck, for example, the server will get the instance of the configuration in memory from a hashmap of instances of VehicleGrupConfiguration and then apply the configuration behavior that this message must have, e.g: like time-out, retry... and etc.
I would like to highlight that there are many ways to implement this situation, but this example shows that a prototype pattern is very powerful in matters of performance and design patterns.
As the documentation says, creating a bean Foo with prototype scope is same as calling:
Foo foo = new Foo(dependency1, dependency2, ...);
foo.initialize(dependency7, dependency8...);
The only good reason to use a prototype scope bean instead of new that is when the dependencies used for creation and initialization of the instance should be kept outside the code that needs a new instance.
As an example:
// need to explicitly mention dependencies here
public void createdWithNew(Dependency dependency1, Dependency dependency2) {
Foo foo = new Foo(dependency1, dependency2, ...);
foo.doSomething();
}
// Dependencies managed in class Foo by Spring
public void createdWithSpring(Foo foo) {
foo.doSomething();
}
An example is if you wanted to write persistence code similar to EJB2 Java Entity beans, such as
Person p = ...
p.setName("John Doe");
p.save(); // write to DB
Instead of using the JPA way
Person p = new Person();
p.setName("John Doe");
personService.save(p); // write to DB
In the entity bean code style, the person instance needs to know how it should be persisted, so it needs to be injected with persistence details that the code writing a person should not be aware about.
Another example:
If you want to use the non-threadsafe SimpleDateFormat Java class in many places of your application, with a format pattern from a configuration file(maybe using different formats depending on other conditions). Instead of creating a new format instance in all those places loading also the formatting string from a file (or spring property), you could use the prototype scope to get a fresh instance every time, with the details of setting the common format being in one place.
Jacob Orshalick (author of Seam Framework: Experience the Evolution of Java EE ) said:
Outjection allows you to make variables available from the current context for injection or access through EL. This can be beneficial if you want to loosely couple several components that inject the same context variable (like the current user, the hotel being booked, etc). If you want to avoid outjection, an alternative is to use an #Factory method or set the value directly into the context through: Contexts.getConversationContext().set("myVarName", myVar)
Another benefit is performance. By outjecting a value to the context, you can bypass having to pass through your component to get that value. This is especially applicable in the case of data tables with JSF (see this discussion). But, as you will see in the discussion you could also use #BypassInterceptors to achieve the same benefit.
Outjection is really a convenience, but the same benefits can definitely be achieved through other means. Do note that outjection was not included in Web Beans and will either be deprecated or completely removed in Seam 3, so this is further reason to avoid it when possible.
We have an application with a lot of outjections and we've started to get rid of them. He said:
but the same benefits can definitely be achieved through other means.
but which are these other means? How to remove the outjections? In ASP.NET for instance you have session variables. In Seam, you can outject var in session (a benefit in some situations).
Or page scope: (for instance in jsf cycle the backing bean is called multiple times (sometimes). You have an account which is loaded from an accountId page param. You can load the account, outject it with a page scope and you can use its properties greatly. OR (to avoid outjection) is to have a loadAccount() method where you take the account from the db whenever you need it...WORST!)
I do not think that:
Contexts.getConversationContext().set("myVarName", myVar)
is a method of how to avoid outjection.
This only calls the same context where the outjected variable is saved and modifies it in a profound way (i think it's exactly what #Out do in the background).
Question 1: What do you think guys about their intention? Do you have specific info about how they will replace it?
Question2: How do you avoid the use of outjection?
Thanks in advance.
I think the best way you can achieve "outjection" is by using #Factory. Its advantage:
It can be #In-jected into another component
It can create any value, not just component instance
It calculate the value once, and just once
It can be triggered by JSF page (I am not sure whether you must enable Seam Transaction Management in order to get this feature)
So if you have a JSF page that needs to access a #Factory more than one time, It is calculated just once. If a value needs to be calculated each time it is requested, so you need a #Unwrap method. For instance, #{currentDate} built-in component is implemented as follows
#Name("org.jboss.seam.faces.facesContext")
#Scope(ScopeType.STATELESS) // ScopeType.STATELESS is similar to Spring prototype scope
public class CurrentDate {
#Unwrap
public Date getCurrentDate() {
return new java.sql.Date(System.currentTimeMillis());
}
}
regards,
To avoid outjection just add a getter to your field in your backing bean, so instead of:
#Name("myBean")
public class MyBean{
#Out
private SomeBean someBean;
}
you will have:
#Name("myBean")
public class MyBean{
private SomeBean someBean;
public SomeBean getSomeBean(){
return someBean;
}
}
and in your xhtml/jsp file you will have to call the getter instead but this have some issues too because everytime you call the getter all the Seam Interceptors will be applied to that call so you probably will need to add #BypassInterceptors to prevent that from happening.
And yes I also think that
Contexts.getConversationContext().set("myVarName", myVar)
is just doing what outject does but manually.