java - que - servlets y jsp
Diferencia entre cada instancia de servlet y cada subproceso de servlet en servlets? (6)
Esta pregunta ya tiene una respuesta aquí:
¿Hay varias instancias de clase servlet? Mientras escucho "cada instancia de servlet" ¿Alguien puede explicar esto?
Aunque ya hay algunas respuestas buenas, ninguna de ellas habló sobre una aplicación web Java implementada en un entorno distribuido. Este es un escenario práctico donde en realidad se crean múltiples instancias de un solo servlet. En un entorno distribuido, tiene un conjunto de máquinas para gestionar la solicitud y la solicitud puede dirigirse a cualquiera de estas máquinas. Cada una de estas máquinas debe ser capaz de manejar la solicitud y, por lo tanto, cada máquina debe tener una instancia de su MyAwesomeServlet en su JVM.
Por lo tanto, la afirmación correcta sería que solo hay una instancia por JVM para cada servlet, a menos que implemente SingleThreadModel.
SingleThreadModel en palabras simples dice que solo tiene que tener un hilo por instancia de Servlet, por lo que básicamente necesita crear una instancia por solicitud futura para manejarlo, lo que básicamente elimina el concepto completo de manejar solicitudes de forma paralela y no es se considera una buena práctica ya que la creación e inicialización del objeto servlet toma tiempo antes de que esté listo para procesar la solicitud.
Cuando se inicia el contenedor Servlet, este:
- lee
web.xml
; - encuentra los Servlets declarados en el classpath; y
- carga y crea instancias de cada servlet solo una vez .
Aproximadamente, así:
String urlPattern = parseWebXmlAndRetrieveServletUrlPattern();
String servletClass = parseWebXmlAndRetrieveServletClass();
HttpServlet servlet = (HttpServlet) Class.forName(servletClass).newInstance();
servlet.init();
servlets.put(urlPattern, servlet); // Similar to a map interface.
Esos servlets se almacenan en la memoria y se reutilizan cada vez que la URL de solicitud coincide con el url-pattern
asociado del servlet. El contenedor de servlet luego ejecuta un código similar a:
for (Entry<String, HttpServlet> entry : servlets.entrySet()) {
String urlPattern = entry.getKey();
HttpServlet servlet = entry.getValue();
if (request.getRequestURL().matches(urlPattern)) {
servlet.service(request, response);
break;
}
}
El GenericServlet#service()
a su vez decide qué doGet()
, doPost()
, etc. invocar basándose en HttpServletRequest#getMethod()
.
Verá, el servletcontainer reutiliza la misma instancia de servlet para cada solicitud. En otras palabras: los servlets se comparten entre todas las solicitudes . Es por eso que es extremadamente importante escribir el código del servlet de la manera segura, lo que es realmente simple: simplemente no asigne los datos de la solicitud o del ámbito de la sesión como variables de instancia de servlet, sino solo como variables locales del método. P.ej
public class MyServlet extends HttpServlet {
private Object thisIsNOTThreadSafe;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object thisIsThreadSafe;
thisIsNOTThreadSafe = request.getParameter("foo"); // BAD!! Shared among all requests!
thisIsThreadSafe = request.getParameter("foo"); // OK, this is thread safe.
}
}
De acuerdo con Java Servlet Specification Version 3.0 (páginas 6-7), habrá una instancia por declaración por JVM, a menos que el servlet implemente SingleThreadModel, en cuyo caso puede haber varias instancias por JVM.
No puede haber múltiples instancias de clase servlet. Incluso cuando hay una instancia del servlet, es capaz de manejar múltiples solicitudes. Por lo tanto, es aconsejable no usar variables de nivel de clase.
No, solo hay una instancia del servlet que se reutiliza para múltiples solicitudes de varios clientes. Esto lleva a dos reglas importantes:
- no utilice variables de instancia en un servlet, excepto para los valores de toda la aplicación, que se obtienen con mayor frecuencia de los parámetros de contexto.
- no
synchronized
métodos en un servlet
(Lo mismo ocurre con los filtros de servlets y jsps)
Para aquellos que conocen JavaScript real (no solo una biblioteca), los servlets pueden verse como objetos de función . Como objetos funcionales, la tarea principal de ellos es hacer algo , en lugar de almacenar información en sus cofres. No es necesario crear una instancia de más de una instancia de cada objeto funcional, con el mismo razonamiento de que los métodos de clase Java se comparten entre todas las instancias de esa clase.