Join GitHub today
GitHub is home to over 36 million developers working together to host and review code, manage projects, and build software together.Sign up
ResourceBundleMessageSource should allow for custom PropertyResourceBundle subclass [SPR-12666] #17265
Property files, resource bundles, and therefore property resources bundles incur a lot of duplication (in practice) because there is no way for one entry to refer to other entries.
Lines 431 to 433 of org.springframework.context.support.ResourceBundleMessageSource hard-code a specific instance of PropertyResourceBundle:
These lines should be:
Then two corresponding protected methods "createPropertyResourceBundle" should be created (with one calling the other). For example:
This would allow for systems to override the specific type of PropertyResourceBundle. Once in place, it is then possible to write properties that refer to other properties, such as:
Currently, this is not possible due to lines 431 - 433.
Juergen Hoeller commented
Semantically, this isn't quite as trivial as introducing such template methods... since they are only being called from
For those template methods to cleanly apply, we'd either have to always use our custom
We'll see what we can do for 4.2 here.
Alternatively, have you tried extending Spring's own
Dave Jarvis commented
A few items of note.
This architecture seems over-engineered. The ReloadableResourceBundleMessageSource class has a few lines where a java.util.Properties class is instantiated (e.g., lines 348 and 568), which violates the DRY principle; additionally, several lines contain "new PropertiesHolder()", which also violate DRY.
These lines should delegate creation to a protected method, which would permit subclasses to override a single method to provide customization.
Next, using a PropertiesPersister seems to offer no advantages over polymorphism. Further, the PropertiesPersister doesn't allow for extending the implementation of the Properties instance used to load the resource bundle. This is due to the following interface definition:
The method takes a pre-instantiated Properties instance, which precludes any possibility of changing the behaviour for getProperty(). The only option that this particular design allows is load-time changes, such as:
This, however, is not an extensible design because the ResolvedProperties class, which overrides getProperty() to perform the substitution, cannot be injected. Even if the customized ResolvedProperties class could be used with this design (by changing the code to perform load-time substitutions instead of query-time), it is still a lot more code to write compared with a polymorphic solution:
Juergen Hoeller commented
Alright, so for 4.2, I've introduced a
FWIW, I do not agree that repeated
Hope that helps for your purposes,