Reputation: 53
I want to create a singleton in Java that requires reading from a file configuration to instanciate, amongst other logic (so it's not just a new MySingletonObject()).
What's the proper way to achieve that in Spring ? I was wondering if I should do the following:
public interface MySingletonObjectAccessor {
MySingletonObject getInstance();
}
@Service
public class MySingletonObjectAccessorImpl implements MySingletonObjectAccessor {
private MySingletonObject mySingletonObject;
@Override
public MySingletonObject getInstance() {
return mySingletonObject;
}
MySingletonObjectAccessorImpl() {
this.MySingletonObject = // complex logic here, that includes reading from a config file
}
}
the usage would then be:
@Autowired
MySingletonObjectAccessor msoa;
MySingletonObject mso = msoa.getInstance();
Am I on the right track ? If so, what would be the correct naming convention for the MySingletonObjectAccessor service ?
Upvotes: 0
Views: 776
Reputation: 91
If you are using singleton as config then use @Component
and use @Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
for singleton.
If it is configuring a file the use FileConfig as class name, as per java standards class name must specify the what it have and what it can do. Ex:- FileReadConfig, FileUploadConfig, DBConnectConfig, EagerInitializedSingleton, StaticBlockSingleton, EnumSingleton ....,
Example:-
@Configuration
public class MySingletonObject {
private MySingletonObject mySingletonObject;
public static final String FILENAME = "/Users/xxx/Projects/xxx/config.xml";
private XMLObject config = null;
private boolean loadConfig(String fileName) {
BufferedReader reader;
String line;
String content = "";
try {
reader = new BufferedReader(new FileReader(fileName));
while ((line = reader.readLine()) != null) {
content += line;
}
} catch (IOException ex) {
LOGGER.log(Level.SEVERE, null, ex);
return false;
}
/**
* IF there is no content, the file must not be valid
*/
if (content.length() <= 0) {
return false;
}
this.config = new XMLObject(content);
return true;
}
private Configuration() {
boolean result = this.loadConfig(FILENAME);
if (!result) {
if (!this.createConfig(FILENAME)) {
System.exit(0); //Catastrophic
}
}else{
mySingletonObject = new MySingletonObject ();
}
}
@Bean("mySingletonObject")
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
public MySingletonObject getMySingletonObject () {
return mySingletonObject;
}
}
Now
@Autowired
MySingletonObject msoa;
Upvotes: 0
Reputation: 1512
You can define a Bean and add a scope to make it singleton.
@Configuration
class MySingletonBeanConfiguration {
//default is singleton scope
@Bean
public MySingletonBean mySingletonBean() {
return new MySingletonBean();
}
}
Upvotes: 2
Reputation: 2490
You could have a public Configuration class like this in your Spring-scanned packages:
@Configuration
public class MySingletonProvider {
@Bean
public MySingleton nameTheMethodExactlyLikeTheBeanNameYouWant(@Value("${singleton.xml.file}") String xmlConfigFile) {
Library lib = new Library(xmlConfigFile);
return new MySingleton(lib);
}
}
Upvotes: 0