How to read unique key in spring for every request - spring

I have requirement to access a particular variable in every service and dao classes. This variable is generated in controller class and passed to service layer and dao layer.
e.g. in Service layer : getService(String key)
in Dao : getTable(String key)
This key is basically used to store error codes in a map with the reference of the key. This key is generated for each service when the request is received in the server. This key is a random number.
Is there a way to fetch this key from spring context so that it can be fetched every time it is required to be used, Instead of passing it every where.

I think its better to pass the value via method argument through each layer. If you are trying to minimize the number of arguments in you methods, it is better to Introduce a Parameter Object.
However, if all the beans that required the value of variable are defined with Request Scope, then you could define a VariableHolder<T> bean to store the value of the variable.
The controller with call variableHolder.set(value) and all the other beans will call variableHolder.get() to obtain it.

Related

#RequestScoped in Quarkus having same hashcode for all request bean

I have used #RequestScoped with quarkus framework. My requirement is for every request new object must be created. But Whenever I have checked the hashcode for all bean for all request then it was same. Means as per my understanding if the first request is there it will create one bean which having some hashcode ,whenever second request will come it will create another bean with different hashcode .But in reality it was same hashcode. Can any one help me to know reason behind it ?
#RequestScoped beans, as well as all other normal-scoped beans, are not injected directly. Instead, a so called client proxy is injected. This client proxy, on each method invocation, looks up the correct instance (in this case, an instance belonging to the "current" request) and forwards the method invocation to it.
So, what you're observing is totally expected. There's one instance of the client proxy, but that doesn't mean there is not a dedicated instance for each request.
There's one twist to it. I said that all methods are forwarded to the correct instance, so you might expect that hash codes would be different for different requests. That isn't the case, though, because the CDI spec says:
The behavior of all methods declared by java.lang.Object, except for toString(), is undefined for a client proxy. Portable applications should not invoke any method declared by java.lang.Object, except for toString(), on a client proxy.
So no, hash codes don't have to be different. If you really want to prove that each request gets a different instance, generate a unique ID in the constructor of the bean class, and expose it though some method.

How to detect if a bean is instantiated on each HTTP request ?

I'm using the #Scope annotation with value of "request".
How do I check if the given object with the "Scope" annotation is instantiated on each http request ?
Do the object (bean) have some identifier (hashcode ) ? And, I don't mean the bean id.
System.identityHashCode(theBeanVariable)
Print the hashes and check the objects are the same or not.
You gotta believe!
No, I'm kidding. Methods I used so far:
In eclipse if you stop application on a breakpoint you can check the id of every object in Variables tab. Every new instance of object has new id. You probably can find a place in your code that is executed after every (or some) request.
If you can set some fields of this bean via a web page, go and do it and then open the same page in new tab in your web browser. If request scope is working, fields you set should have old values (the one that are set on creation of object).
Maybe these are not uber-pro methods, but may be enough in some cases and you don't have to add anything in your code.

Returning an object from a Spring Batch job / processor

I have a Spring Batch job that reads in a very large fixed length file and maps it just fine to an object. Validated all of the data in the associated processing task.
Being rather new to Spring and Spring Batch I am wondering if it is possible to get out of the job, a fully populated object to be used in a particular case when I am running the job as part of another process ( that I would like to have access to the data).
I realize that I could do the above without Batch, and it seems to be designed with scope limitations for its purpose.
I could serialize the objects in the processor and go that route but for my immediate satisfaction I am hoping there is a way to get around this.
Thanks
In my #configuration class for the batch processing, I created a class variable (it is a list of the object I want to get back) and instantiated with the no arg constructor.
My Step, ItemReader, LineMapper are setup to use a list for input. The custom FieldSetMapper takes that list instantiated from the constructor as a parameter and adds to the list as the file is read and mapped. Similarly my custom ItemProcessor takes the list as input and returns it.
Finally I created a ReturnObjectList bean that returns the populated list.
In my main I cast the AnnotationConfigApplicationContext getbean to the list of that object type. I am now able to use the list of objects generated from the fixed file in the scope of my main application.
Not sure if this is a healthy work around in terms of how Spring Java config is supposed to work, but it does give me what I need.

Transfer an object from controller to dao

I am getting an token from request(the token is required to identify the user) to initialize user object in interceptor. Then i want to transfer this user object to controllers(i can put the user object to httprequest and get it in controller method, is this the best practice???, i am not sure) than transfer it to service and dao layer. But i don't want to add this user object as parameter to every method between controller->service->dao. What is the best practice of this?
Thanks in advance.
How about using a request-scoped bean to hold the token. You could reference the bean in your controller and set the token on it. Then in lower DAO layers could you reference the same bean to pull out the token. That would save having to pass the token down the method stack.
Alternatively you could use ThreadLocal storage directly which is effectively request scoped, but since you're using Spring, it would be cleaner and make more sense to leverage it's own request scope functionality.

How to handle externally stored default values in Domain Class

I want to be able to set default values for some fields in my domain classes.
Till now I had a class which stored a Map of settings for my whole project, with a task in mind to move this map into a redis database.
The day has come and I moved all the data to redis and created a nice spring bean to get/set the values.
However...
it seems that default values are set on the domain class instance before bean is injected.
This kind of breaks the whole process.
Also... there's an issue with unit tests.
I've created a class which implements the same interface as the spring bean and holds test values. I wanted to inject it into domain classes, but this fails as well.
So right now I'm trying to find a good way to handle externally stored defauls values for my domain classes with ability to run unit tests.
Any thoughts?
There are a few different approaches you could take:
Introduce a separate bean with the default values so that those are supplied in the same way as they were before. In a separate higher level context or later on in application startup, you could then override the bean definition with the one that pulls from the database
Use a BeanPostProcessor or BeanFactoryPostProcessor to specify the default values, then use your new bean for retrieving new values
If neither of these answers is helpful, please post your setup and example code so I can get a clearer picture of what you're trying to do.
What I did in the end:
I've created a class which is connecting to Redis and gets me all the data I require.
For unit testing I've created a copy of this class, it implements the same interface but instead of getting the data from Redis it has a simple Map inside and get's the data from there. In the end it acts the same, but the data is stored internally. So in my unit tests I just inject this Unit test version of this class where appropriate.
Probably not the best solution there is but it worked for me for the last few months.

Resources