Hi, I was reading some valuable comment on the Singleton Antipattern in Rod Johnson's "J2EE Development without EJB".
He also mentioned when it can be usefull, e.g. during container bootstrap of a standalone application.
This is exactly what I did in one of my current projects and I'm wondering if I did the right thing or if the antipattern still could be avoided.
It is a Spring project (much like Spring iBATIS JpetStore) and it is standalone, a runner class in the form of an NT service (JavaService by Alexandria) is serving as "bootstrap", but - unfortenately - it is part of a custom library I cannot (or better should not) modify.
Yet I want the application context, bean definitions, etc. initialized only once as default behaviour, so I chose to create the following singleton :
A custom propery loader class reads the config locations from a context.properties file (very similar to contextConfigLocation in web.xml in case of a Spring webapp) :Code:public class SpringFactory { private static SpringFactory springFactory; private static BeanFactory beanFactory; private SpringFactory() { } public static SpringFactory getInstance() { if (springFactory == null) { springFactory = new SpringFactory(); } return springFactory; } public BeanFactory getBeanFactory() { return getBeanFactory(false); } public BeanFactory getBeanFactory(boolean reload) { if (beanFactory == null || reload) { loadApplicationContext(); } return beanFactory; } private void loadApplicationContext() { Properties props = PropertyLoader.loadProperties("context"); String contextConfigLocation = props.getProperty("contextConfigLocation").trim(); String[] configLocations = contextConfigLocation.split(","); ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(configLocations); beanFactory = (BeanFactory) appContext; } }
The rest is obvious, an application would have access to a bean by calling the getBeanFactory() method.Code:# SPRING CONTEXT # ============== contextConfigLocation = applicationContext.xml, dataAccessContext-local.xml, test-beans.xml
There is also an issue of context reloadability; if there is only a change in the bean configuration I would not want to restart the whole container, so I forsaw a getBeanFactory(boolean reload) method to handle this.Code:BeanFactory beanFactory = SpringFactory.getInstance().getBeanFactory(); ...
So, is this a good approach or are there better ways to do it ? I'm very interested in the opinion of you experts :wink:
Kind regards,
M


Reply With Quote