简体   繁体   中英

proper way of exposing singleton class through interface

I have a singleton class that has to be exposed as a service to other applications using interface.

for example:

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
   }

}

Now if I want to expose all the services of this class through interface, here is my first attempt :

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

and when MySingleSingletonClass implements this interface :

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();
   }

}

I see two problems with this kind of implementation,

first if I use a framework like spring, and I try to get a bean of type MyServiceInterface how will the class be instantiated? I read that spring will still call the private contractor of the class using reflection. will this instance still be singleton ?

Second , if Spring gives me the instance already, I don't see the point of calling getInstanceThroughService() method using the instance itself. feels like there is a problem with this implementation.

thank you

Typical spring beans are singletons by default!

@Service
public class MySingleSingletonClass{

   public int methodA(){...}
}

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

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

In this scenario you will have 3 beans: - ONE MySingleSingletonClass - one ConsumerA - one ConsumerB

The reference mssc in ConsumerA and ConsumerB will point to the SAME instance of MySingleSingletonClass .

So you do not need the have to implement the standart Singleton pattern, Spring will do it for you.

You can use spring's factory-method http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html to tell spring to use getInstanceThroughService() to get new instances which in turn you will give same cached instance and hence maintaining your singleton.

But, if you are using spring then you dont need to maintain singleton object yourself. Spring does it automatically (unless of-course your class is being used outside of spring container in same jvm/classloader).

Spring is a framework that implements a design pattern called inversion of control (or IoC). One application of IoC is to allow an external framework to configure and instantiate parts of the application, indeed, this is the function of spring beans. Spring beans allow you to configure application resources using a configuration file and access those resources in your application.

Singletons (and prototype beans) are managed by spring, so there is no need to implement the Singleton design pattern yourself. You only need to create a Spring-compliant bean and declare it in the Spring configuration. You can then access it from the application context.

Your bean can still implement an interface as it normally would, and you can use the interface in your application.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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