在单个tomcat服务器上配置多个spring boot应用程序

时间:2019-02-06 15:24:28

标签: spring-boot tomcat

我正在开发两个Spring Boot应用程序,这些应用程序必须部署在现有的单个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配置的Spring Boot中实现相同的目标。到目前为止,我发现的最佳解决方案是使用自定义@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());
    }
}

它有三个缺点。

  • SpEl #{servletContext …}(可能)为null,整个末尾 @PropertySource中的值将被忽略。现在也来不及 ServletContext中的ApplicationContext。的 PropertySourcesPlaceholderConfigurer是更早创建的。
  • 不允许多次部署(应用名称​​ manager 为 硬编码在媒体资源中)。
  • 必须在user-defaults.properties中定义所有可重写属性。 application.properties中的值始终覆盖值形式 spring documentation的财产来源。

我也试图像这样向propertyPlaceholderConfigurer注入上下文路径

@Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer(@Value("#{servletContext.contextPath}") String contextPath) {
    System.out.println(contextPath);
    final PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
    return pspc;
}

How to use servlet contextPath with 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的情况下如何加载外部配置吗?

0 个答案:

没有答案