繁体   English   中英

如何使现有的Java类/接口实现单例?

[英]How can I make an existing Java class/interface implementation a singleton?

假设我在Spring中使用ApplicationContext实现。

ApplicationContext是Java Spring Framework中的接口,我无法更改它。

如何确保该实现只能有一个实例?

例如。 我有以下代码-

public class ApplicationContextSingleton 
{
     private static ApplicationContext context;
     private static int numberOfInstances = 0;

     public static ApplicationContext getApplicationContext()
     {
         if(numberOfInstances == 0)
         {
             context = new ClassPathXmlApplicationContext("spring.xml");
             numberOfInstances++;
         }
         return context;
     }
}

这样,我可以确保只有一个ApplicationContext实例,条件是按以下方式获得它:

ApplicationContext context = ApplicationContextSingleton.getApplicationContext();

但这并不能阻止其他程序员说-

ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); 

从而创建一个新的ApplicationContext。 如何防止这种情况发生?

您希望将ApplicationContext设为单例,因此我用自己的自定义类覆盖了该类,确保它首先出现在类路径上,并使其具有私有构造函数。

也就是说,如果您不愿意将其设置为单例。 正如其他答案和评论所指出的那样,还有更好的方法可以解决您的问题。

应该注意的是,覆盖库片段通常不是一个好主意,因为这可能会在以后引起麻烦,尤其是当您尝试升级框架版本时。

除非有人能提出一些新颖的创意,否则我认为没有办法。 这类似于尝试将int单例化。 只是不会发生,因为您无法控制未编写的类的使用。 您将只需要信任您的开发人员就不会创建第二个上下文。

另外,我几乎可以保证这是不可能的 ,但是您可以获取spring的完整源代码,进行一些代码更改以使上下文成为单例,然后自行构建。 不太可能的解决方案,但是我觉得还是需要指出来。

之所以无法这样做,是因为

Spring并未将ClassPathXmlApplicationContext实现为Singleton模式。 通知每个人您都有一种实用方法来访问上下文对象,并且使用new创建上下文非常昂贵。

  1. 使用自动构建系统,该系统在将代码提交到您的软件存储库时就可以生成您的代码。
  2. 将工具(例如FindBugs或PMD)集成到您的构建过程中。 如果这些工具触发了某些条件,则使构建失败并不允许生成任何工件。
  3. 在集成工具中创建一个案例,以寻找开发人员创建自己的上下文。

因此,您不能阻止他们这样做,但是可以阻止他们将这些事情推送到您的开发,质量保证和产品环境中。 这似乎有些过分,但是这种过程将帮助开发人员完成数百项但不应该做的事情。

Josh Block建议在有效Java中使用枚举。 这不是到该书的链接 ,但它显示了他和较旧的(替代)方法

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM