Reputation: 1230
I want to implement Singleton pattern in context of Spring application. So even my singleton object will be created by spring.
To do that:
I put a class that implements ApplicationContextAware to get beans from spring context:
public class AppContext implements ApplicationContextAware
{
/**
* Private instance of the AppContext.
*/
private static AppContext _instance;
/**
* @return the instance of AppContext
*/
public static AppContext getInstance()
{
return AppContext._instance;
}
/**
* Instance of the ApplicationContext.
*/
private ApplicationContext _applicationContext;
/**
* Constructor (should never be call from the code).
*/
public AppContext()
{
if (AppContext._instance != null)
{
throw (new java.lang.RuntimeException(Messages.getString("AppContext.singleton_already_exists_msg"))); //$NON-NLS-1$
}
AppContext._instance = this;
}
/**
* Get an instance of a class define in the ApplicationContext.
*
* @param name_p
* the Bean's identifier in the ApplicationContext
* @param <T>
* the type of the returned bean
* @return An instance of the class
*/
@SuppressWarnings("unchecked")
public <T> T getBean(String name_p)
{
return (T) _applicationContext.getBean(name_p);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext_p) throws BeansException
{
_applicationContext = applicationContext_p;
}
}
My singleton class:
public class MySingleton {
private static MySingleton instance= null;
public static final String BEAN_ID = "mySingletonInstanceId";
private MySingleton(){}
public static MySingleton getInstance(){
return AppContext.getInstance().getBean(mySingletonInstanceId.BEAN_ID);
}
}
My application.xml file:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:cxf="http://cxf.apache.org/core" xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">
<!--some code-->
<bean id="idAppContext" class="com.AppContext" />
<bean id="mySingletonInstanceId" class="com.MySingleton"/>
<!--some code-->
</beans>
Do you think that my code is good ?
instance field is no longer necessary?
Considering that Spring will manage every everything, getInstance() has only to return singleton instance created by spring ?
Upvotes: 1
Views: 2853
Reputation: 21
I came to the same conclusion and a similar implementation as you. If someone needs a Singleton Pattern then this is the way to do it with Spring. I wished I had seen this post earlier.
Some people don't understand that the Singleton Pattern is different than the Singleton defined by Spring which is explained here: Singleton design pattern vs Singleton beans in Spring container
It is tricky to get around the reflection that is used by Spring which effectively ignores the private access modifier.
Having said this, some people hate the Singleton Pattern as can be seen by this post: http://puredanger.github.io/tech.puredanger.com/2007/07/03/pattern-hate-singleton/
This is causing me to reconsider using the Singleton Pattern Design and instead use the Spring Singleton instead.
Upvotes: 2