通过接口公开单例 class 的正确方法

proper way of exposing singleton class through interface

我有一个单例 class,它必须作为服务公开给使用接口的其他应用程序。

例如:

public class MySingleSingletonClass{

    private static final MySingleSingletonClass THIS_INSTANCE = new MySingleSingletonClass();

    private MySingleSingletonClass() {}

    public static MySingleSingletonClass getInstance(){
       return THIS_INSTANCE;
    }

    //do other staff
   public int methodA(){
     //some service
   }

}

现在如果我想通过接口公开这个class的所有服务,这是我的第一次尝试:

public interface MyServiceInterface{
    int methodA();
    MyServiceInterface getInstanceThroughService(); 
}

并且当 MySingleSingletonClass 实现此接口时:

public class MySingleSingletonClass implements MyServiceInterface{

    private static final MySingleSingletonClass THIS_INSTANCE = new MySingleSingletonClass();

    private MySingleSingletonClass() {}

    public static MySingleSingletonClass getInstance(){
       return THIS_INSTANCE;
    }

   @Override
   public int methodA(){
     //some service
   }

   @Override
   MyServiceInterface getInstanceThroughService(){
     return MySingleSingletonClass.getInstance();
   }

}

我发现这种实现有两个问题,

首先 如果我使用像spring 这样的框架,并且我尝试获取类型为MyServiceInterface 的bean 如何实例化class?我读到 spring 仍会使用反射调用 class 的私人承包商。这个实例仍然是单例吗?

Second,如果 Spring 已经给我实例,我看不到使用实例本身调用 getInstanceThroughService() 方法的意义。感觉这个实现有问题

谢谢

典型的 spring bean 默认是单例的!

@Service
public class MySingleSingletonClass{

   public int methodA(){...}
}

@Service
public class ConsumerA{
   @Autowired
   private MySingleSingletonClass mssc;
}

@Service
public class ConsumerB{
   @Autowired
   private MySingleSingletonClass mssc;
}

在这种情况下,您将拥有 3 个 bean: - 一个 MySingleSingletonClass - 一个消费者A - 一个消费者 B

ConsumerAConsumerB 中的引用 mssc 将指向 MySingleSingletonClass 的同一个实例。

因此您无需实施标准单例模式,Spring 会为您完成。

您可以使用 spring 的工厂方法 http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html 告诉 spring 使用 getInstanceThroughService() 来获取新实例,这反过来您将提供相同的缓存实例,因此维护你的单身人士。

但是,如果您使用的是 spring,那么您不需要自己维护单例对象。 Spring 会自动执行(当然除非您的 class 在同一 jvm/classloader 中的 spring 容器之外使用)。

Spring 是一个实现称为 inversion of control(或 IoC)设计模式的框架。 IoC的一个应用是允许外部框架配置和实例化应用程序的一部分,确实,这就是spring beans的功能。 Spring bean 允许您使用配置文件配置应用程序资源并在您的应用程序中访问这些资源。

单例(和原型 bean)由 spring 管理,因此无需自己实现单例设计模式。您只需要创建一个符合 Spring 的 bean 并在 Spring 配置中声明它。然后您可以从应用程序上下文访问它。​​

您的 bean 仍然可以像往常一样实现接口,并且您可以在应用程序中使用该接口。