I am working on a spring boot api where I have used a query string and doing some replace operations on it on every get request but even after I trigger a new request the string is in the same state as that of previous GET call and the query gets messed up.
Here's my code:
private static String GET_SETS = "Select * from table #check#";
Now I have 1 method in the same repository which gets called on a get request:
public PagedList getSets(Map params) {
if (!StringCheck.isEmpty(flattenMap.get("entity_name"))) {
GET_SETS = GET_CODE_SETS.replace("#check#", " WHERE e.#entity_name# = ?");
values.add((String)flattenMap.get("entity_name"));
} else {
GET_SETS = GET_SETS.replace("#check# #status_check#", "");
}
}
Now whenever a GET request is triggered,some changes are done to GET_SETS string according to map values,and again in the next requests the same changes are there.
How to solve this? I want the query string to be whats defined at the start on every request. Thanks
Your problem is most likely caused by using the default scope, which is singleton, when creating your Spring components.
Spring provides the following scopes for creating beans
(source):
singleton (default): Scopes a single bean definition to a single object instance for each Spring IoC container
prototype: Scopes a single bean definition to any number of object instances.
request: Scopes a single bean definition to the lifecycle of a single HTTP request. That is, each HTTP request has its own instance
of a bean created off the back of a single bean definition. Only valid
in the context of a web-aware Spring ApplicationContext.
session: Scopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring
ApplicationContext.
application: Scopes a single bean definition to the lifecycle of a ServletContext. Only valid in the context of a web-aware Spring
ApplicationContext.
websocket: Scopes a single bean definition to the lifecycle of a WebSocket. Only valid in the context of a web-aware Spring
ApplicationContext.
If we don't specify any scope explicitly, the default singleton scope is used. This means that the service/component is shared between multiple injections, hence it is reused for multiple GET requests.
In order to get rid of this behavior, we might use something like request scope, although in this case we have to take care of thread-safety as well.
Other solution is to not use member variables and try to use local variables for things such as GET_SETS.
Related
I have a callable type class. It is a annotated with #component. I would like to create multiple instances of the callable class. To do so, I am using the application context. The problem is it simply does not work.
Refer Bean scope you want to use:
https://docs.spring.io/spring-framework/docs/3.0.0.M3/reference/html/ch04s04.html#:~:text=2%20The%20prototype%20scope,method%20call%20on%20the%20container).
singleton - once for each IoC container, your application context
prototype- multiple beans for multiple object instance
request - in case of web aware app context, each bean to a particular HTTP request, and new instance for another
session- for each HTTP session.
global session - as what name says.
depending on your use select scope as well explained by #BeUndead.
I saw 'application' scope in the following blog. Is it true?
http://www.concretepage.com/spring/spring-bean-scope-example-using-scope-annotation-and-xml-for-singleton-prototype-request-session-global-session-and-application-scope-with-scoped-proxy
Because, as per my surfing, I got to know spring has only the below 5 scopes. Please correct me if I'm wrong.
Singleton
Prototype
Request
Session
Global Session
There is a section on the official doc which is related to the bean scopes:
7.5 Bean scopes
Basically, they define the next:
singleton (Default) Scopes a single bean definition to a single object instance per Spring IoC container.
prototype
Scopes a single bean definition to any number of object instances.
request
Scopes a single bean definition to the lifecycle of a single HTTP request; that is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.
session
Scopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.
globalSession
Scopes a single bean definition to the lifecycle of a global HTTP Session. Typically only valid when used in a Portlet context. Only valid in the context of a web-aware Spring ApplicationContext.
application
Scopes a single bean definition to the lifecycle of a ServletContext. Only valid in the context of a web-aware Spring ApplicationContext.
websocket
Scopes a single bean definition to the lifecycle of a WebSocket. Only valid in the context of a web-aware Spring ApplicationContext.
Furthermore, as Spring 3.0 exists other scope thread scope but is not registered by default, moreover you could even create your own scope:
As of Spring 3.0, a thread scope is available, but is not registered
by default. For more information, see the documentation for
SimpleThreadScope. For instructions on how to register this or any
another custom scope, see the section called “Using a custom scope”.
There is a section which explains how to define your custom scope:
7.5.5 Custom scopes
Respect to Application scope, they define it as next:
The Spring container creates a new instance of the AppPreferences bean
by using the appPreferences bean definition once for the entire web
application. That is, the appPreferences bean is scoped at the
ServletContext level, stored as a regular ServletContext attribute.
It also explains the difference between a Spring singleton bean:
This is somewhat similar to a Spring singleton bean but differs in two
important ways: It is a singleton per ServletContext, not per Spring
'ApplicationContext' (for which there may be several in any given web
application), and it is actually exposed and therefore visible as a
ServletContext attribute
So in case you are looking to use with XML:
<bean id="apps" class="com.App" scope="application"/>
Or annotation:
#ApplicationScope
#Component
public class App {
// ...
}
application
Scopes a single bean definition to the lifecycle of a ServletContext. Only valid in the context of a web-aware Spring ApplicationContext.
Follow the link for more details:
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-factory-scopes
Do we have concept of page scope in spring3?
Suppose user open multiple tab then if data is stored in session then in some situation things may go wrong. Imagine user will open two tab in the browser. And in both these tab he is working on same page so that he can complete his work faster. So if some data is referred from session then in that case application can reach to an error state.
So to avoid this I want to store data in page scope,so that each page data will not be mixed in session? is it directly available in spring or I need to write my own conversation logic and page scope?
In Spring you have following scope :
singleton - (Default) Scopes a single bean definition to a single object instance per Spring IoC container.
prototype - Scopes a single bean definition to any number of object instances.
request - Scopes a single bean definition to the lifecycle of a single HTTP request; that is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.
session - Scopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.
global session - Scopes a single bean definition to the lifecycle of a global HTTP Session. Typically only valid when used in a portlet context. Only valid in the context of a web-aware Spring ApplicationContext.
Do we have concept of page scope in spring3?
--> In Spring you don't have page scope but you can configure your particular bean to use request scope.
Reference : Spring Documentation
I have a web application that is based on Spring. There is defined a bean that holds some class MyClass that is passed also with beans to MyEndpoint that extends AbstractMarshallingPayloadEndpoint.
MyClass has set some boolean parameter in beans to true.
If my application will change this parameter programically to false, does next request will have it also set to false or it will contains a default bean parameter - true ?
It depends on the scope of the bean (which will default to singleton, if you don't specify one).
If it is of singleton scope, there is one instance of that bean in the application context, and each time you ask for that bean, you get that single instance. If you change it in a request with this scope, then the change will be maintained.
If it is of prototype scope, a new instance is given to you (created with the same parameters) each time you ask the application context for it. If you change it in a request with this scope, then the change will be ignored when you get another instance of this object.
These are the two most commonly used (at least with my time in Spring). There are other scopes (request, session, globalsession), but you should read the documentation on them that Spring provides.
If you want this property to change dynamically according to your application business logic and not only to be reset on every new request (otherwise Request scope will do the magic) consider Factory Methods (especially Lookup Method Injection)
#Autowired works only once.
What to do to make it wire the bean every time the Servlet is recreated?
My web-app (Tomcat6 container) consists of 2 Servlets. Every servlet has private fields.
Their setters are marked with #Autowired
In the init method I use
WebApplicationContextUtils
...
autowireBean(this);
It autowires the properties marked with #Autowired once - during the initialization of the Servlet.
Any other session will see these fields values, they will not be rewired after the previous session is destroyed.
What to do to make them rewire them each time a Servlet constructor is called?
a) Put the autowiring into the constructor?
Or better 2) get a web app context and extract a bean from there?
There seems to be some misunderstanding about how the container works. Servlets are essentially singletons, you don't get a new servlet everytime someone calls the server. Storing state in private fields on a servlet is pretty much an error.
What is the scope and life-cycle of the stateful part of your request processing? If it's just the life of the request then you can take whatever on your servlet is stateful and move it into another class. Then you can define a prototype bean for that class and use getBean at the start of the request to get a new one. If you want to start getting fancy you could write a filter that puts a new bean into a ThreadLocal at the start of each request.
If your state needs to span multiple requests, you need to start keeping state or a key that points to the state storage on the web session, or look into using a conversation framework.
Try using scope as prototype for that bean #Scope("prototype")
You may try to use #Scope("session")