I have copied a sample Spring Boot SPA. I want to understand, what happens if multiple people use the web page via the URL. Does Java create an instance of the web application per call? Memory resources are not shared, right, i.e. if there is a list object appended to, each user sees their own list?
The default scope for a spring-boot bean is a singleton. Assuming your bean is not managing state you should be fine with the default behavior:
https://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch04s04.html
4.4.1 The singleton scope
When a bean is a singleton, only one shared instance of the bean will be managed, and all requests for beans with
an id or ids matching that bean definition will result in that one
specific bean instance being returned by the Spring container.
To put it another way, when you define a bean definition and it is
scoped as a singleton, then the Spring IoC container will create
exactly one instance of the object defined by that bean definition.
This single instance will be stored in a cache of such singleton
beans, and all subsequent requests and references for that named bean
will result in the cached object being returned.
Now if you are using a bean that's stateful and want a new bean used per request, you can define the scope of that bean to be prototype:
4.4.2 The prototype scope
The non-singleton, prototype scope of bean deployment results in the creation of a new bean instance every time a
request for that specific bean is made (that is, it is injected into
another bean or it is requested via a programmatic getBean() method
call on the container). As a rule of thumb, you should use the
prototype scope for all beans that are stateful, while the singleton
scope should be used for stateless beans.
Spring resources like #Service and #Repository and #RestController are stateless singletons. Only a single instance is created to serve the application.
Your implementation of the list at scope level will determine whether or not it is shared. If you define the List in the Controller, as in your example, then every user will have access to the same list. You can use multiple browsers to see that the list is shared. Based on the example, this is fine, as getting "all" should really mean getting all.
If you wanted each user to have their own list, you would have to implement some sort of Session or back-end process to associate each individual user with their own list.
This isn't shared-nothing like PHP or Rails. Java is so slow starting up that firing up a new instance of the application for every request isn't an option.
Check out the spring-boot sample application source code, there's a main method on the SpringbootJQueryAjaxClientApplication class, like this:
public static void main(String[] args) {
SpringApplication.run(SpringBootJQueryAjaxClientApplication.class, args);
}
this is the main method like for any Java program, what happens here is it starts the self-hosted servlet container and installs the application into it, then waits for http requests.
It is one process, where every request is served by a thread, so memory is shared. Spring components like com.javasampleapproach.jqueryajax.controller.RestWebController (scoped as singleton by default) are instantiated once in the web application, and every request calls methods on the same instance.
Related
My understanding is that a prototype-scoped Java bean class is instantiated every time it is requested, as opposed to singleton-scoped Java beans which are instantiated once when the application starts up.
My question is: how much overhead does using the prototype scope cause?
Does the Spring framework make any attempt to recycle prototype-scoped objects to reduce the overhead caused by repeated instantiation?
Is the overhead caused by prototype scoping enough to warrant efforts to make as many of my Java bean classes stateless so that I can apply singleton scope to them?
You should not think of overhead between the prototype and singleton scope, but only the way they are used. If they are stateless objects that will live throughout the life time of the application, the correct scope is singleton. Many beans exist in that scope, for example controllers, beans in a service or persistence layer. Most beans related to Spring Security framework are also stateless and live in singleton scope.
If you want to create a brand new bean for a specific processing and then discard it when it has been used, then it is a use case for the prototype scope. As I mainly used spring for Web application I seldom used prototype scoped beans, but used request scoped beans which have a close use case: they are created for a HTTP request processing. The only point of attention is that if you have to inject a prototype or request scoped bean in a singleton bean, you will have to use a proxy that allows to connect to the current prototype bean (may be in thread storage) and not a bean that would have been created when the singleton was.
Using prototype scope is the same as if you were to instantiate using 'new' except that the new object will be managed by Spring. Spring will be able to apply aspects, inject dependencies, etc.. There will also be the overhead of the proxy class created to wrap the object.
Spring will not attempt to reuse the instances.
If you do not want to create a new instance whenever you reference the bean then you should not be using a prototype. Your solution will either require independent instances, maybe due to concurrency, or it will allow for a singleton. It is unlikely that the memory used by the object will be the deciding factor for what scope you use.
I want to understand what is use of request scoped beans in spring? I know it lives only till the request is alive. But I can't think of any practical use.
It is what it is, you get a bean scoped for the current request. That means that whenever you ask the spring context to give you a specific bean which is request scoped, you will get different instances for different requests. If you ask for the same bean twice in the same request, you'll get the same instance as you would expect.
Please note that in order to use request scoped beans in a singleton bean (the default bean scope in Spring), you will need a scoped proxy. That means, you'll need to use a singleton proxy instance in your singleton beans that will actually delegate all method invocations to the per-request scoped instances of that type.
See this answer on spring scoped proxy bean for a very nice and detailed explanation.
I am using Guice in a project. Since it is the first time, I am wondering about how to keep and pass around state, i.e. objects that contain some user input or long lived objects that are needed elsewhere (not where they were injected the first time).
For instance, my application has a Server which the user can start and stop. Furthermore, the user can enter some data which leads to state that needs to be preserved in memory.
At the moment I see two possibilities:
have a Context class with scope #Singleton and some references to other classes that keep my state and offer me certain functionality.
The Context class would give me access to the Server instance, to user data, other services etc.
The instances of the Context may be injected by Guice.
Thus, if I want to stop my server, I would require the Context as a dependency (and not the server).
This goes a bit against the recommendation on the Guice website (inject direct dependencies instead of accessing the "real" dependency with chained getters).
annotate all classes with #Singleton that should exist only once and are injected in several other classes. As a consequence, I would have only a singleton server, somewhere a class with the user data, etc.
The singleton pattern (GoF) is said to be bad design. Thus, I am wondering whether I should minimize the use of #Singleton or whether this is a different story using Guice respectively dependency injection in general.
Are there any other possibilities or a better approach?
I think most of your questions is related to Dependency Injection Paradigm. first of all Using DI doesn't mean every managed bean should be Singleton. The managed beans have their own life cycle. they can be instantiated on every access / request / session or being singleton.
The other thing you should be care about is with DI we usually wire-up our main application design. you should think of your domain objects and their relations instead of DI(Guice/Spring).
for instance in your case if you need a Service Object in a bean so you have the relationship between these two classes and no need to to have a relation to Context!
if data inserted by different users are visible to all users so make the service singleton in your application. if the states of Server bean for each user are different so make the scope of bean Session to allow every user have his own Server bean.
Im really new to java, jsf, jsp, and I need to learn how it works quickly. So the website Im using to practise has some terms etc that I dont know what they mean and Im hoping somebody can explain what they mean and how/what they are used for:)
Requestscoped
Applicationscoped
Sessionscoped
EntityManager
and could someone walk me through what these lines do?
#RequestScoped
public class Dao {
#DataRepository
#Inject
private EntityManager entityManager;
First of all, in Java (5 and higher), "things" starting with a # (e.g. #Deprecated) are called annotations.
Annotations provide data about a
program that is not part of the
program itself. They have no direct
effect on the operation of the code
they annotate.
Your JavaBeans needs to be configured to a scope if you want to use it in JSF (Definitions can be found here).
#RequestScoped: Objects with this scope are visible from the start of the request until the end
of the request. Request scope starts at the beginning of a request and ends when the
response has been sent to the client. If the request is forwarded, the objects are visible
in the forwarded page, because that page is still part of the same request/response
cycle. Objects with request scope can use other objects with none, request, session,
or application scope. If you have to think it in terms of servlet, the managed bean is stored in the HttpServletRequest until the end of the request (when the response is sent to the client). After that, the bean no longer exists in the request.
#SessionScoped: An object with session scope is visible for any request/response cycle that
belongs to a session. Objects with this scope have their state persisted between
requests and last until the object or the session is invalidated. Objects with session
scope can use other objects with none, session, or application scope. Basically, these objects are stored in a HttpSession (refer to Servlets again). Each session has a session ID (known as JSESSIONID) that the bean is associated with.
ApplicationScoped: An object with application scope is visible in all request/response cycles
for all clients using the application, for as long as the application is active. In terms of Servlet, this could be, managed bean stored in a ServletConfig.
#NoneScoped: Objects with this scope are not visible in any JSF page. When used in the configuration file, they indicate managed beans that are used by other managed beans in the application. Objects with none scope can use other objects with none scope.
For EntityManager, this is associated with persistence context. It is used to create and remove persistent entity instances, to find entities by their primary key identity, and to query over all entities. For more, refer to the JPA (Java Persistence API) Specification, or Hibernate.
#Inject, means that the instance is injectable. They follow the infamous crase word of Depency Injection or Inversion of Control (IOC). What this basically mean, is that when the resource (in your case EntityManager entityManager is needed, the JEE container instantiates the resource for you (without you needed to instantiate it directly through e.g. a constructor, etc.).
I have no clue what #DataRepository means. Never seen it before.
I hope this helps you.
These terms are usually associated with a dependency injection framework like guice and not with java in particular.
http://code.google.com/p/google-guice/wiki/Scopes describes the various scopes that are built into guice.
By default, Guice returns a new instance each time it supplies a value. This behaviour is configurable via scopes. Scopes allow you to reuse instances: for the lifetime of an application (#Singleton), a session (#SessionScoped), or a request (#RequestScoped). Guice includes a servlet extension that defines scopes for web apps. Custom scopes can be written for other types of applications.
How can I set a spring bean at application level (declaratively)and use the member of it on jsp ?
are you using spring-MVC?
If so, as part of your controller class, have an instance variable that has your bean injected into it. Then, when handling the request in the controller method, add that instance var to your model and return it. This way it will be accessible in the JSP.
Actually, rather than having to put it into every request in one (and possibly more controllers), you can use the ServletContextAttributeExporter to have Spring place the bean in the J2EE container's applicationScope and have it available all the time in all of your JSPs. This would be much cleaner and simpler than binding it to your controllers and writing code to make it available to your requests.