Статьи

Способ чтения свойств с переменной интерполяцией

Недавно я попытался определить и прочитать глобальные свойства на сервере приложений. Преимущество такого свойства, настроенного на сервере приложений, — оно может использоваться всеми веб-приложениями, развернутыми на этом сервере. Каждое развернутое приложение может читать одно и то же свойство, которое настраивается только один раз в одном месте. Я попытался сделать системное свойство с другим системным свойством в части значения. На сервере приложений JBoss / WildFly вы можете, например, определить системное свойство в файле конфигурации standalone.xml . Я установил свойство exporting.service.config.file .

1
2
3
<system-properties>
    <property name="exporting.service.config.file" value="${jboss.server.config.dir}\exporting\exporting-service.properties"/>
</system-properties>

jboss.server.config.dir указывает на каталог базовой конфигурации в JBoss. Это свойство устанавливается автоматически JBoss. В этом примере у нас есть так называемая Variable Interpolation . Определение из Википедии : «Переменная интерполяция (также подстановка переменных или расширение переменных) — это процесс вычисления строкового литерала, содержащего один или несколько заполнителей, с получением результата, в котором заполнители заменяются соответствующими значениями». Другим примером для заполнителей ${...} в значении свойства может быть следующая конфигурация:

1
2
3
application.name=My App
application.version=2.0
application.title=${application.name} ${application.version}

Теперь, когда мы пытаемся получить системное свойство из первого примера с помощью Java System.getProperty(...)

1
2
  
String globalConfigFile = System.getProperty("exporting.service.config.file");

мы получим значение ${jboss.server.config.dir}\exporting\exporting service.properties . Заполнитель ${jboss.server.config.dir} не разрешен. Во втором примере такие же проблемы.

Какой самый простой способ прочитать свойства с переменной интерполяцией? Ну, есть Spring Framework с PlaceholderConfigurerSupport и так далее. Но иметь такую ​​большую структуру, как зависимость, непросто. Есть ли легкая библиотека? Да, конечно — Конфигурация Apache Commons . Конфигурация Apache Commons предоставляет специальные префиксные имена для свойств, чтобы оценить их в определенном контексте. Есть например:

  • sys: этот префикс помечает переменную как системное свойство. Конфигурация Commons будет искать системное свойство с заданным именем и заменять переменную на ее значение.
  • const: префикс указывает, что переменная должна интерпретироваться как постоянное поле члена класса. Имя переменной должно быть полностью определенным именем класса.
  • env: префикс ссылается на свойства среды ОС.

Некоторые примеры из документации:

1
2
3
user.file = ${sys:user.home}/settings.xml
action.key = ${const:java.awt.event.KeyEvent.VK_CANCEL}
java.home = ${env:JAVA_HOME}

Теперь я могу добавить необходимую зависимость в свой проект Maven

1
2
3
4
5
<dependency>
    <groupId>commons-configuration</groupId>
    <artifactId>commons-configuration</artifactId>
    <version>1.10</version>
</dependency>

установить префикс sys: before jboss.server.config.dir

1
2
3
<system-properties>
    <property name="exporting.service.config.file" value="${sys:jboss.server.config.dir}\exporting\exporting-service.properties"/>
</system-properties>

и напишите следующий код

1
2
3
4
5
6
7
import org.apache.commons.configuration.SystemConfiguration;
 
...
 
SystemConfiguration systemConfiguration = new SystemConfiguration();
String globalConfigFile = systemConfiguration.getString("exporting.service.config.file");
...

String globalConfigFile на моем ноутбуке имеет значение C:\Development\Servers\jboss-as-7.1.1.Final\standalone\configuration\exporting\exporting-service.properties . Префикс sys: помечает переменную как системное свойство. Конфигурация Commons будет искать системное свойство с заданным именем и заменять переменную на ее значение. Полный код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.configuration.SystemConfiguration;
 
...
 
PropertiesConfiguration propertiesConfiguration = new PropertiesConfiguration();
SystemConfiguration systemConfiguration = new SystemConfiguration();
String globalConfigFile = systemConfiguration.getString("exporting.service.config.file");
if (globalConfigFile != null) {
    try {               
        propertiesConfiguration.setDelimiterParsingDisabled(true);               
        propertiesConfiguration.load(globalConfigFile);
    } catch (ConfigurationException e) {
        LOG.log(Level.INFO, "Cannot read global properties");
    }           
}

Любое отдельное свойство может быть прочитано, например, как

1
2
3
4
5
6
propertiesConfiguration.getString("someKey")
propertiesConfiguration.getString("someKey", someDefaultValue)
propertiesConfiguration.getBoolean("someKey")
propertiesConfiguration.getBoolean("someKey", someDefaultValue)
propertiesConfiguration.getInteger("someKey")
propertiesConfiguration.getInteger("someKey", someDefaultValue)

usw. Это все. Дайте мне знать, если вы знаете еще один простой способ чтения свойств с переменной интерполяцией.