如何在Web应用程序中处理单例?

Bla*_*man 15 java singleton

根据我的理解,单例基本上是当你有一个私有成员代表你想拥有单个实例的对象时.然后在构造函数中初始化成员对象.

此对象的所有引用都是通过公共属性完成的,而public属性只引用已经实例化的私有成员.

现在在Web应用程序中,这是如何工作的?在tomcat关闭之前,单个实例是否只在容器中挂起(比如tomcat)?

Gre*_*ill 6

如果您的执行环境使用多个类加载器,那么每个类的实例都会得到一个单例.如果您的单例类被加载到不同的类加载器中,那么它实际上是两个不同的类,然后将有两个"单例"实例.

您可以在文档中找到有关Tomcat类加载器的一些信息.


Adr*_*ter 5

应该区分Singleton模式及其实现.大多数(如果不是全部)常见的Singleton实现都会遇到上面提到的类加载以及序列化,线程安全等问题.请参阅https://www.securecoding.cert.org/confluence/display/java/MSC07-J.+Prevent+multiple + instantiations + of + singleton + objects,用于全面概述.

但是,最广泛意义上的Singleton模式可以保证在特定上下文中是唯一的任何服务.Singleton的唯一性只能相对于给定的范围指定,如类加载器,JVM,容器或集群; 唯一性的级别取决于实现,应根据应用程序的要求进行选择.

导致使用单例的两个非常常见的要求是依赖注入(使用工厂的cq)和内存缓存.在这两种情况下,都有良好的框架可以将Singleton方面隐藏在客户端之外,并在例如企业应用程序容器中提供足够的唯一性.对于依赖注入Spring,Guice或Pico会浮现在脑海中.对于缓存,我知道Ehcache是​​领先的解决方案,但肯定还有更多.(有趣的琐事:'ehcache'这个名字是回文)

一般来说,单身人士的使用是"不受欢迎的",并被视为反模式.另一方面,依赖注入和缓存等服务需要工作的唯一性.因此,如果我们宣称反单身,同时使用Spring或Ehcache等,我们就会愚弄自己.

在我看来,对Singletons的恐惧源于许多可能的,并且丰富的不良实现.即使Singleton实现本身是"安全的",在整个应用程序中直接调用它(通过静态访问)会导致紧密耦合和可测试性差.

如果您的应用程序中有Singleton工厂,您可以进行的改进是重构其客户端,以便在需要依赖项时不会调用工厂,而是提供私有字段和公共setter,允许注入依赖项.然后,您可以集中客户端的初始化,可能在同一个工厂中,并使客户端代码保持干净,松散耦合和可测试(您现在可以注入模拟依赖项).这也可能是引入像Spring这样的依赖注入框架的第一步.

我希望在这个漫长而漫无边际的帖子中的某个地方,我帮助回答了你的问题!( - ;