I was looking for the idiomatic way to implement thread-safe lazy initialization for a configuration collection retrieved from the DB inside a Spring bean.
I decided to adapt the initialisation-on-demand holder pattern as follows:
public class Security {
private static ParametersDao DAO;
/**
* Initialisation-on-demand Holder pattern
*/
private static class StaticHolder {
public static final Set<String> VALID_EMAIL_ADDRESSES;
static {
VALID_EMAIL_ADDRESSES = DAO.loadEmailAddresses();
}
}
private ParametersDao parametersDao;
public void setParametersDao(ParametersDao parametersDao) {
this.parametersDao = parametersDao;
}
public Set<String> getValidEmails() {
if (parametersDao == null) throw TooSoonException();
DAO = parametersDao;
return StaticHolder.VALID_EMAIL_ADDRESSES;
}
}
What are the issues to watch out for adapting this approach like this, apart from the timing issue between needing the valid email addresses and IoC container initialisation?
By storing state inside a static nested class, you are limiting yourself to only being able to instantiate a single instance of this object. If you ever need to use multiple DAO implementations, or add another dependency that needs to change, this could cause a problem. Such requirements seem to me to be quite likely in order to sufficiently unit test this code.
I’d suggest simply using a synchronized method and allocating the object if its reference is null, unless you have a good reason to believe the overhead of this approach would be too high.
3