配置文件可以在运行时动态交换吗?

时间:2019-04-18 19:25:23

标签: spring-boot

我正在使旧版Web应用程序现代化。此应用程序的困难之一是配置模型。当前,每个客户都有一个单独的应用程序实例,每个实例具有单独的配置属性。这些属性当前存储在Tomcat的context.xml中,并且有一个JNDI帮助程序在启动时提取这些属性。由于一个Tomcat实例=一个context.xml,因此可以使用。但是现在我们希望为所有客户提供一个实例(或实例集群)。

我认为通常可以在会议中完成。但是在这种情况下,那将是一个很大的重构。配置值保存在带有静态设置器和获取器的pojo中,在整个代码库中都大量调用它们。 JNDI帮助程序在启动时在pojo上设置配置,这就是应用程序查找其配置值的方式。

在开发改进此模型时,我们正在采取一些措施,而不是进行大量重构。因此,目标是在朝着良好方向前进的同时尽可能少地改变。我正在考虑的事情之一是使用Spring-Boot配置文件。代替每个客户一个单独的实例,每个客户可以有一个弹簧启动配置文件。然后,在每个HTTP请求中,一个servlet过滤器可以通过观察用户身份并在请求期间激活他们的配置文件来激活适当的配置文件,我希望这样便可以从过滤器中将值注入到静态设置器中。

我知道这很不正常,但是我想跳出框框。

我了解ConfigurableEnvironment.setActiveProfiles。我不确定的是,这将在引导阶段之后是否主动注入属性值更改,以及是否可能导致性能问题或出于其他任何原因听起来很疯狂。

2 个答案:

答案 0 :(得分:1)

从春季documentation起:

  

您可以在应用程序运行之前通过调用SpringApplication.setAdditionalProfiles(…​)以编程方式设置活动配置文件。也可以使用Spring的ConfigurableEnvironment界面来激活配置文件。

答案 1 :(得分:0)

这与弹簧轮廓无关!您可以通过编程的方式来操作它们,但是有一次,您的JVM(应用程序)中只有一个spring上下文。 您想使用用户特定的属性进行操作吗?这是每个请求,或者是每个会话范围,而不是应用程序范围! 我建议您使用以下情况:

1。)在对您的客户进行身份验证之后,将其值存储在CustomerConfig实例(非静态!)中,并将此customerConfig存储到请求或会话属性中

2。),您可以在HttpFilter中执行此操作:

if (session.isNew)
{   // read customerConfig from DB or resources etc...
    session.setAttribute("customerConfig",customerConfig);
}

3。)在POJO类中,您可以像

ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
CustomerConfig cc =(CustomerConfig)attr.getRequest().getSession().getAttribute("customerConfig");
parameter = cc.getYourCustomerProperty();

4。)在组件,服务等中,您可以自动连接请求,例如:

@Component
@Scope("request")
public class FooBar {
    @Autowired 
    private HttpServletRequest request;

    public void function()
    { CustomerConfig config = request().getSession().getAttribute("customerConfig");
      parameter = cc.getYourCustomerProperty();
      //...
     }  
}