How can I have a global variable in Spring per request? - java

I'm translating an application based on REST using Spring Framework. Now I need to translate some responses based on the language of the request. For example:
/get-me-an-answer/?lang=es Spanish
/get-me-an-answer/?lang=en English
/get-me-an-answer/?lang=fr French
I have the variable language_code as a static variable in a class named Translang
class Translang {
...
public static String language_code = null;
...
}
The problem is with multithreading, when a new request come will change the language and if another previous request is executing can probably answer in the language modified and not in the original language it requested.
That's the reason of my question: How can I have a global variable in Spring per request to avoid this problem?

Seems that ThreadLocal is what you are looking for as per request is performed by a separate thread.
This class provides thread-local variables. These variables differ
from their normal counterparts in that each thread that accesses one
(via its get or set method) has its own, independently initialized
copy of the variable. ThreadLocal instances are typically private
static fields in classes that wish to associate state with a thread
(e.g., a user ID or Transaction ID).

I would suggest to implement a context that navigates throw the flow of your request, so with this, you will pass this context among the entire transaction, once you have that domain element, you need to create a new one by each request that you receive. Currently your class is not thread safe, this can be fixed also changing the scope of your bean.

Related

Single class file on server memory using Spring causing problems

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.
}
}

Spring : Singleton VS Prototype

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

Managed-Bean best practice

I'm back to building my Managed-Bean of a hashMap. ( Creating a HashMap of type <String , Object> ) I have defined a class
public class AppProperties {
private String appRepID;
private String helpRepID;
private String ruleRepID;
private String filePath;
private Vector formNames;
private Database appDB;
// all the getters and setters
}
The managed bean will create an Application Scope variable of the hashMap. In the constructor of the Bean I build the the values for each Application (the key) by collecting all the info from a number of different places. The repIDs are pretty straight forward. My question/concern is it wise to store the appBD in the Application Scope variable. I have read that one should never store a Notes Object in a Scoped Variable would that be an issue here? Secondly, if that is the case I could add a method to the AppProperties that would open the DatabaseByReplicaID when ever the method to get the Application Database is called, which adds a fair bit of overhead to the process as the database object will get called many many time in the life cycle of the application.
Right, you shouldn't store Notes objects in scope variables and properties of beans.
Because They are not serializable (a must for certain scopes) and they will be recycled between lifecycles. More precisely, since they are based on C-handles, XSP engine creates Notes objects between request-response cycle and when response written back to the user, they are all going to be recycled. Trying to keep them in the memory will make them 'toxic' for your server.
You can define a method in your bean (like GetHelpDb()), create and return it whenever you need. It's not a huge performance cost. Because Domino server implements caching for databases. When you open a database over and over again will not generate additional disk I/O.
The best practice for interacting with Notes data in such situation would be caching. I frequently use this approach in my applications. You might get values in a single method, cache them into HashMap(s) and get them from the map when you need. Using getter method, you may also check a time-based value to handle time-outs.

When to use Spring prototype scope?

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.

Is it OK to use ThreadLocal for storing the requested Locale?

I am working on internationalizing user entered data in a rather large Client/Server (HTTP (Hessian) is used for communication) application which is stored in a database. Users can choose the language they want to see and there is a default language which is used when a translation in the requested language is not present.
Currently a data class may look like this:
class MyDataClass {
private Long id;
private String someText;
/* getters and setters */
}
After internationalization it could look like this:
class MyDataClass {
private Long id;
private Set<LocalizedStrings> localizedStrings;
/* getters and setters */
}
class LocalizedStrings {
private Locale locale;
private String someText;
/* getters and setters */
}
Of course it may be interesting to create a delegate getter in MyDataClass which takes care of getting the text in the correct locale:
public String getSomeText(Locale locale) {
for(LocalizedString localized : localizedStrings) {
if (localized.getLocale().equals(locale)) {
return localized.getSomeText();
}
}
}
In my team there were some concerns though about the need to pass the locale around all the time until they reach the data class. Since all this stuff happens on the server and every request to the server is handled in a dedicated Thread, some people suggested to store the requested locale in a ThreadLocal object and create a backward compatible no-argument getter:
public String getSomeText() {
return getSomeText(myThreadLocalLocale.get());
}
The ThreadLocal then needs to be a global variable (static somewhere) or it needs to be injected into MyDataClass on every single instance creation (we are using spring, so we could inject it if we make our data classes spring managed (which feels wrong to me)).
Using a ThreadLocal for the locale somehow feels wrong to me. I can vaguely argue that I don't like the invisible magic in the getter and the dependency on a global variable (in a data class!). However, having a "bad feeling" about this is not really a good way to argue with my colleagues about it. To help I need an answer with one of the following:
Tell me that my feeling sucks and the solution is great for reasons X,Y and Z.
Give me some good quotable arguments I can use to argue with my colleagues and tell me how to do it better (just always pass locale around or any other idea?)
Although, common practise I don't like to do localizing "deep" within the application.
Intead of this:
public String getSomeText() {
return getSomeText(myThreadLocalLocale.get());
}
We do this:
public LocalizableText getSomeText() {
return new LocalizableText(resourceBundle, "someText");
}
And then do, e.g. in a JSP or output layer:
<%= localizable.getString(locale) %>
The logic itself is language agnostic. We have cases where, after some processing, the application sends out the result by mail, logs it and presents it to the web user in all different languages. So processing together with result generation and then localization must be separate.
This approach is perfectly valid.
For example, Spring makes Locale available using ThreadLocal through RequestContextListener and LocaleContextHolder.
If you create a custom implementation, make sure you handle your ThreadLocal (set/remove) properly.
Using a thread local like you describe is a very common pattern in web applications. See this class in the Spring API as an example:
org.springframework.web.context.request.RequestContextHolder
Use a servlet filter (or similar) to both set the locale in a thread local, and then CLEAR the locale value after the server finished each request. Instead of injecting it in each place it is used, use a static factory/accessor method similar to RequestContextHolder: RequestContextHolder.getRequestAttributes().
ThreadLocal is bad practice. It's global variables and there are plenty of articles about how bad that is, in any language. The fact that Spring uses it does not justify using it. I like the solution cruftex has given. Avoid passing data via global variables.

Categories