【问题标题】:Dynamically switching between properties files based on request header parameter in spring boot applicationspring boot 应用中根据请求头参数动态切换属性文件
【发布时间】:2019-09-28 14:47:33
【问题描述】:

我正在开发一个多租户 REST spring boot 应用程序。我能够根据每个请求中的标头值在不同的数据源之间动态切换。但我的问题出在 application.properties 文件上。不同的租户在其属性文件中对相同的属性具有不同的值。

如何分离每个租户的属性文件,并根据请求标头中的值动态确定要使用的属性文件

【问题讨论】:

  • 您可以使用配置文件并且每个租户拥有一个文件。见docs.spring.io/spring-boot/docs/current/reference/html/…你能确定哪个租户正在调用标头吗?
  • 是的,我能够根据请求中发送的标头识别租户。我已经查看了配置文件,但我不清楚一个类如何根据请求标头值切换配置文件。

标签: java spring spring-boot


【解决方案1】:

您不能在运行时切换配置文件。您的选择仅限于创建一个新的 ApplicationContext,它有其自身的缺点,或者您可以在启动时加载租户属性文件并实现特定于租户的 getProperty 方法以在需要时调用。

这应该处理后一种情况:

@Component
public class TenantProperties {

  private Map<String, ConfigurableEnvironment> customEnvs;

  @Inject
  public TenantProperties(@Autowired ConfigurableEnvironment defaultEnv,
      @Value("${my.tenant.names}") List<String> tenantNames) {

    this.customEnvs = tenantNames
        .stream()
        .collect(Collectors.toMap(
            Function.identity(),
            tenantId -> {
              ConfigurableEnvironment customEnv = new StandardEnvironment();
              customEnv.merge(defaultEnv);
              Resource resource = new ClassPathResource(tenantId + ".properties");

              try {
                Properties props = PropertiesLoaderUtils.loadProperties(resource);
                customEnv.getPropertySources()
                    .addLast(new PropertiesPropertySource(tenantId, props));
                return customEnv;
              } catch (IOException ex) {
                throw new RuntimeException(ex);
              }
            }));
  }

  public String getProperty(String tenantId, String propertyName) {

    ConfigurableEnvironment ce = this.customEnvs.get(tenantId);
    if (ce == null) {
      throw new IllegalArgumentException("Invalid tenant");
    }

    return ce.getProperty(propertyName);
  }
}

您需要将my.tenant.names 属性添加到包含逗号分隔的租户名称列表(name1, name2 等)的主应用程序属性中。特定于租户的属性从类路径中的 name1.properties, ... 加载。你明白了。

【讨论】:

    【解决方案2】:

    Spring 配置文件适用于您的情况。

    如果仅在启动服务之前,从预测租户及其属性的意义上来说,租户是静态的,那么我建议将 tovgo 用于静态配置文件特定文件。

    如果在为其他租户提供服务时可以更改某些属性,那么最好使用配置服务器,这样无需重新启动就可以更改这些属性。

    如果租户是动态的,您可以根据您的数据点选择 db,如果租户数量可能会大幅增加。

    【讨论】:

    • 租户是静态的。我喜欢配置服务器选项并且一直在探索它。但我不清楚应用程序将如何在每个租户的不同配置文件之间切换
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-04
    • 1970-01-01
    相关资源
    最近更新 更多