When are servlets instances created actually? - java

According to the post how do servlets work instantiation servlets, listeners and filters are instantiated when the server parses the web.xml file. But listeners and filters are only getting instantiated. Servlets are not getting instantiated.
So are servlets instantiated at parsing web.xml or when requests come?

It depends on how you configured.
If you want to instantiate during startup, you should give <load-on-startup> in web.xml
else Servlet is instantiated when the container receives the first request.
In either case the same instance is used to serve subsequent requests.

Related

Life cycle management of servlet when SingleThreadModel is used

According to the java docs, it says that If SingleThreadModel is used there are two ways a servlet instance will be created and used
1. Create one servlet instance and make the service() method synchronized and thus allow only one thread to execute the service method.
2. Create a pool of servlets and serve the request by using one servlet instance from the pool for each request.
THe question which I want to ask is I have also read a new Servlet instance is created and destroyed for every request. Now which one is correct
Here's what the spec says (version 3.0, section 2.2):
For a servlet not hosted in a distributed environment (the default), the servlet container must use only one instance per servlet declaration. However, for a servlet implementing the SingleThreadModel interface, the servlet container may instantiate multiple instances to handle a heavy request load and serialize requests to a particular instance.
In the case where a servlet was deployed as part of an application marked in the deployment descriptor as distributable, a container may have only one instance per servlet declaration per Java Virtual Machine (JVMTM)1. However, if the servlet in a distributable application implements the SingleThreadModel interface, the container may instantiate multiple instances of that servlet in each JVM of the container.
Note that you should really not use the single thread model. Just make sure your servlet is thread-sae. A servlet is typically stateless, so you don't have anything to do to make it thread-safe.
From the docs for SingleThreadModel:
Ensures that servlets handle only one request at a time
This is in essence a way to make non thread-safe servlet code work. Note that the container is free to choose any of the two implementations to adhere to the spec:
Create a single instance of the servlet and ensure that it handles only one request at a time
Create a pool of servlet instances and hand over a request to an available servlet instance.

ServletContext parameters: are they per instance or per server?

I have a tomcat server running a webapp. In the webapp's startup, I'm setting few context parameters using an implemented class for interface ServletContextListener. The parameter that I am initializing here are a couple of connection objects for a database running on a different machine.
The doubt that i have is whether the connection objects that I created here are one for each instance (since tomcat creates one instance per client request), or one for the entire webapp itself?.
If it is one per webapp, then can the server handle large simultaneous requests (in the order of thousand request per second) to perform the CRUD operations on the database?.
ServletContext is created one per webApp. The server reads the web.xml file from the web app and creates a ServletContext based on the configuration you provide on web.xml. Once created it is shared between the components of the web app. If you have multiple webapp installed on your server, you will have multiple ServletContext - each for the web app.
For reference please have a look here
A webapp has only one instance of ServletContext and the atributes in ServletContext are application scoped.
Regarding you database connection, it's better to use connection pooling (DataSource) instead of adding Connection objects as attributes in ServletContext.
Not sure if you mean this but the requests are handled by Servlets and not ServletContext.
If your setting an attribute on the ServletContext the attribute will be scoped for the entire application.
From the Java EE 7 Spec:
There is one instance object of the ServletContext interface
associated with each Web application deployed into a container.
only one ServletContext is loaded irrespective of the number of requests made.
This is even the advantage of servlets over CGI.
Hope it helps.

When exactly a web container initialize a servlet?

When exactly a web container initialize a servlet?
Is it guaranteed that it does it at web container start up time?
Thanks.
No, it's not. First, the webapp itself is not guaranteed to be started when the container starts (that depends on the specific container configuration). And even if the webapp is started, the specification says:
Servlets are initialized either lazily at request processing time or eagerly during deployment. In the latter case, they are initialized in the order indicated by their load-on-startup elements.
When exactly a web container initialize a servlet?
Either at the time of loading the web application or on the first request to the servlet. This is configurable in web.xml using load-on-startup flag
Is it guaranteed that it does it at web container start up time?
Nothing is guranteed when it comes to the container. It depends how the contianer is written .The only way to request the container is through configurable param load-on-startup in in web.xml.
Depends on how you are defining and configuring your servlet.
You might find this clearly in docs
Initializing a Servlet
After the web container loads and instantiates the servlet class and before it delivers requests from clients, the web container initializes the servlet. To customize this process to allow the servlet to read persistent configuration data, initialize resources, and perform any other one-time activities, you override the init method of the Servlet interface. A servlet that cannot complete its initialization process should throw UnavailableException.
If you want to participate in that process ovveride init method of the Servlet interface and do the required stuff there.

Life cycle/length of a DataSource injected with #Resource annotation

I'm far from an expert of the intricacies of Resource Injection, and of indeed DataSources in Java, but I generally understand the process of doing a lookup for a predefined JNDI resource to get a datasource from.
Using Resource Injection as an alternate method, the below syntax works:
#Resource(name="jdbc/Foo")
private javax.sql.DataSource con;
However, I am using this in a servlet and as such wondering, how long this injected connection object's value will exist? Presumably, as it's simply an object within the servlet, it will inject when the servlet is first instantiated and exist for the same duration as the servlet (assuming I don't manually change it). Is this correct? Or does the servlet re-inject the resource everytime the servlet is used?
Thanks
A servlet container only ever creates one instance of your servlet. The IoC container you're using will then instantiate and inject the DataSource, so the value in con will remain the same for the life of your servlet, ie. the life of the application.
As to the underlying connection the DataSource is trying to make will, that's up to your datasource.
it will inject when the servlet is first instantiated and exist for the same duration as the servlet
Correct.
Or does the servlet re-inject the resource everytime the servlet is used?
No, this couldn't be happening because each request is served by a different thread. It wouldn't be good if those threads would modify the fields of the servlet. Request processing methods of the servlet must not modify its fields.
Generally container managed resources are injected using #Resources annotation. And container managed resources live as long as the container is running ( unless your are not manually kill it or any exception happens). Several applications can use the same resource object, provided that they live in the same application server ecosystem (same application server or cluster or server domain). But servlets are managed by your applications and lives within the application's scope as long as your application is running! So in terms of life span, if you compare resources are longer living than servlets.
And yes you are right, if you inject resources to a servlet, the reference of the resource will remain from the creation of the servlet to the end of the servlet's life cycle. The injection is not related with, how you are using the servlet or the resource.
Hope, this answers your question, Thanks!

Does each request access the same servlet object?

Does each HTTP request access the same servlet object but in a different thread? or does it create a new thread and new Servlet Instance ?
The container will use the same servlet instance if your servlet don't implement SingleThreadModel.
Otherwise there is no guarantee that the same Servlet object is hit. The container is free to create more servlet instances if it considers necessary. But the requests comes on different threads, not necessarily newly created (as Sanjay mentioned).
From the Servlet 3.0 specification:
For a servlet not hosted in a distributed environment (the default), the servlet
container must use only one instance per servlet declaration. However, for a servlet
implementing the SingleThreadModel interface, the servlet container may
instantiate multiple instances to handle a heavy request load and serialize requests
to a particular instance.
...
Generally the Web container handles concurrent requests to the same servlet by
concurrent execution of the service method on different threads.
Each HTTP request creates a new thread but accesses the same instance of the Servlet.
EDIT: In case of one server node, you will have the same Servlet instance on that node. In case of load balancing/many servers you will usually have one instance per Java VM.

Categories