#java #internationalization #java-platform-module-system #serviceloader
#java #интернационализация #java-платформа-модуль-система #serviceloader
Вопрос:
Предположим, что модуль A (provider) содержит messages.properties
, и мы хотим загрузить его как ResourceBundle из модуля B. Javadoc буквально предлагает следующий подход.
Модуль поставщика:
module provider {
exports provider;
exports provider.spi;
provides MessagesProvider with MessagesProviderImpl;
}
package provider.spi;
public interface MessagesProvider extends ResourceBundleProvider {}
package provider;
public class MessagesProviderImpl extends AbstractResourceBundleProvider implements MessagesProvider {
public MessagesProviderImpl() {
super("java.properties");
}
protected String toBundleName(String baseName, Locale locale) {
return super.toBundleName(baseName.toLowerCase(), locale);
}
}
Потребительский модуль:
module consumer {
requires provider;
uses MessagesProvider;
}
ResourceBundle bundle = ResourceBundle.getBundle("provider.Messages");
Это ОГРОМНАЯ чрезмерная разработка, но, что более важно, такой дизайн несовместим с системой плагинов. Если у вас есть несколько плагинов (поставщиков), очевидно, что они могут использовать только один и тот же интерфейс ResourceBundleProvider. Но текущая реализация ResourceBundle загружает только первую из найденных реализаций.
Интересно, в чем причина такого дизайна, если можно легко сделать что-то подобное:
public class FooClassInProviderModule {
public ResourceBundle getBundle(Locale locale) {
return ResourceBundle.getBundle(LOCAL_PATH, locale, FooClassInProviderModule.class.getModule());
}
}
… и это работает при вызове из потребительского модуля. И это также работает с изображением JRT. Почему весь этот беспорядок с ResourceBundleProvider?
Обновить:
Хорошо, я думаю, я понял. Это не дизайн, это неправильная формулировка javadoc.
Если пакеты ресурсов развертываются в именованных модулях отдельно от вызывающего модуля, эти пакеты ресурсов необходимо загружать от поставщиков услуг ResourceBundleProvider.
Вместо этого следует сказать «Если пакеты ресурсов развернуты в именованных модулях отдельно от вызывающего модуля, и вы не знаете, где именно вам следует использовать ResourceBundleProvider, который полагается на интерфейс ServiceLoader».
Если вы знаете точный модуль, нет необходимости в ResourceBundleProvider.
Комментарии:
1. Если вы точно знаете, какой модуль содержит messages.properties, просто напишите класс в этом модуле с открытым методом, который извлекает ResourceBundle. Нет необходимости в поставщиках.