Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将Tomcat配置为每个应用程序只引发一个Servlet_Java_Tomcat_Servlets - Fatal编程技术网

Java 将Tomcat配置为每个应用程序只引发一个Servlet

Java 将Tomcat配置为每个应用程序只引发一个Servlet,java,tomcat,servlets,Java,Tomcat,Servlets,据我所知,Tomcat可以根据自己的意愿创建尽可能多的servlet副本,以便为请求提供服务 这迫使我的servlet没有重量级状态,而是将所有状态存储在(单例)servlet上下文中 是否可以将Tomcat配置为将我的servlet视为单例,并始终只生成一个servlet实例而不考虑负载?不,我不这么认为。然而,实际上tomcat只会实例化一个servlet,即使JavaEE规范允许它实例化多个servlet。大多数(如果不是全部的话)MVC框架都依赖于这一假设,并在servlet中存储大量配

据我所知,Tomcat可以根据自己的意愿创建尽可能多的servlet副本,以便为请求提供服务

这迫使我的servlet没有重量级状态,而是将所有状态存储在(单例)servlet上下文中


是否可以将Tomcat配置为将我的servlet视为单例,并始终只生成一个servlet实例而不考虑负载?

不,我不这么认为。然而,实际上tomcat只会实例化一个servlet,即使JavaEE规范允许它实例化多个servlet。大多数(如果不是全部的话)MVC框架都依赖于这一假设,并在servlet中存储大量配置状态


如果您希望安全起见,那么不要将状态存储在servlet中,将其粘贴到另一个使用singleton模式的类中,并从servlet中引用该singleton。

您不希望将状态存储在servlet中的另一个主要原因是它引入了同步问题,如果您希望在集群环境中运行,则会出现序列化问题,等等。如果您不在servlet内部存储状态,而是在会话(或请求)对象中存储状态,那么所有这些问题都很容易避免


所以真的。。。为什么要存储状态?这是一种“推荐做法”,有其原因。

根据Servlet规范,(v2.4,第2.2节“实例数”):

SRV.2.2实例数

对于不在分布式环境中托管的servlet(默认情况下),servlet 容器每个servlet声明只能使用一个实例。但是,对于servlet 通过实现
SingleThreadModel
接口,servlet容器可以 实例化多个实例以处理繁重的请求负载并序列化请求 适用于特定的实例


对您的问题的回答很简单:不要实现
SingleThreadModel
,也不要在
web.xml
描述符文件中多次声明您的servlet。

Matt B也是如此。在学习本课程之前,我曾经严重烧伤过一次。我将状态信息存储在servlet对象中的statics中。在我们只有一台服务器的测试中,这一切都非常有效。然后我们部署到生产环境中,在那里我们有一个服务器集群,在我们最终发现它之前,我们遇到了非常奇怪的错误

使用会话或应用程序对象。这就是他们的目的


故事的寓意:当结构设计师提供了一个工具,并说当你想做X时使用这个工具,这可能是有原因的。对忽略这些建议要非常谨慎。

我喜欢Spring MVC——它可以用作servlet上相当薄的包装器,但它提供了很多好处,包括依赖注入,它可以让您将共享对象/服务分配给控制器(相当于servlet),而无需硬编码它们(这会使测试/维护变得更好)。尝试教程或阅读类似“Spring in Action”的书开始。分离控制器和模型逻辑对于良好的MVC设计来说与分离视图(我将把共享状态和服务计算为“模型”)一样重要。“JavaEE规范允许它实例化多个”--视情况而定。一个容器(即tomcat)每个声明只能实例化一个servlet,除非servlet实现
SingleThreadModel
接口。SingleThreadModel保证每个线程一个实例,但我不认为省略它保证每个容器一个实例。servlet规范保证每个容器一个实例,除非您使用SingleThreadModel。在在这种情况下,容器被允许多次实例化servlet。相关问题-是否保证容器在调用destroy()后不会保留对servlet的引用?是。请查看SRV.2.3.4节,服务结束:"一旦对servlet实例调用destroy方法,容器可能不会将其他请求路由到该servlet实例。如果容器需要再次启用servlet,则必须使用servlet类的新实例来启用该servlet。destroy方法完成后,servlet容器必须释放servlet实例,以便他有资格进行垃圾收集。”