Я занимаюсь разработкой двух приложений с весенней загрузкой, которые необходимо развернуть на существующем одном сервере Tomcat.Один из них (app1) должен запускаться по контекстному пути manager .Другой (app2) должен запускаться два раза в контекстах customer1 и customer2
Tomcat
+ manager (app1)
+ customer1 (app2 with configuration 1)
+ customer2 (app2 with configuration 2)
Я хотел бы иметь каталог с такими конфигурациями
/opt
+ configuration
+ manager
| + application.properties
+ customer1
| + application.properties
+ customer2
+ application.properties
, где каталог в конфигурации совпадает с контекстным путем, и каждое приложение загружает свою конфигурацию из соответствующего (пути) файла.
Я провел некоторое исследование, но не нашел никакого связанного ответа.В большинстве советов рекомендуется использовать переменные среды для непосредственного изменения свойств конфигурации или для установки нового местоположения конфигурации с помощью переменной среды spring.config.location
.Тем не менее, это влияет на все приложения на сервере.
В моем предыдущем приложении (без загрузки) я использую эту конфигурацию XML:
<bean id="appPropertyConfigurer" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<value>classpath:app.properties</value>
<value>file:/opt/myappconfig/app.properties</value>
<value>file:${catalina.base}/my_app_config/conf.default.properties</value>
<value>file:${catalina.base}/my_app_config/conf/#{servletContext.contextPath != '' ? servletContext.contextPath : 'ROOT'}.properties</value>
</list>
</property>
</bean>
, которая в основном принимала одно свойство за другим сверху внизснизу и прочитайте конфигурацию.Тот, что в пути: ${catalina.base}/my_app_config/conf/*context_path*.properties
всегда побеждал.
Я пытаюсь добиться того же при весенней загрузке в конфигурации Java.Лучшее решение, которое я нашел до сих пор, - это следующая конфигурация с пользовательской @PropertySource
:
@PropertySource(//
value = { //
"classpath:user-defaults.properties", //
"file:${my_app_config}/manager/application.properties", //
// This line is silently ignored even 'ignoreResourceNotFound = false'. The servletContext is probably null
"file:${my_app_config}/#{servletContext.contextPath != '' ? servletContext.contextPath : 'ROOT'}/application.properties"//
}, //
ignoreResourceNotFound = false//
)
@Configuration
public class PropertyConfig implements ApplicationContextAware {
/** PropertySourcesPlaceholderConfigurer has to be registered in order to resolve ${} place-holders. */
@Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
return pspc;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
// Here I can't get the servlet context. This method get called much later then
ServletContext servletContext = applicationContext.getBean(ServletContext.class);
System.out.println("Servlet context is" + servletContext.getContextPath());
}
}
. У нее есть три недостатка.все последнее значение в @PropertySource
игнорируется.Также слишком поздно получить ServletContext
от ApplicationContext
.PropertySourcesPlaceholderConfigurer
создан намного раньше.
Он не допускает многократное развертывание (имя приложения
manager жестко задано в источнике свойств). Все перезаписаносвойства должны быть определены в
user-defaults.properties
.Значения
application.properties
всегда перезаписывают значения из источника свойств согласно
весенней документации .
Я также пытался вставить контекстный путь к propertyPlaceholderConfigurer
, например,
@Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer(@Value("#{servletContext.contextPath}") String contextPath) {
System.out.println(contextPath);
final PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
return pspc;
}
Предложено в Как использовать сервлет contextPath с PropertySource? , но я получил только
Unsatisfied dependency expressed through method 'properties' parameter 0;
nested exception is org.springframework.beans.factory.BeanExpressionException:
Expression parsing failed; nested exception is
org.springframework.expression.spel.SpelEvaluationException:
EL1008E: Property or field 'servletContext' cannot be found on object of type
'org.springframework.beans.factory.config.BeanExpressionContext' -
maybe not public or not valid?
Вопрос
Кто-нибудь испытывал, как загрузить внешнюю конфигурацию, где servletContextPathтакже принимается во внимание?