gpt4 book ai didi

spring - 如何根据租户在运行时选择spring配置?

转载 作者:行者123 更新时间:2023-12-04 12:32:27 25 4
gpt4 key购买 nike

我希望能够根据用户在运行时所属的租户来选择特定的 Spring(或 Grails)上下文配置。假设我使用 Spring Security 并在登录期间检索tenantId。
想象一下,现在我有两个租户,他们支付不同的佣金。如何在没有太多管道的情况下将特定服务注入(inject) Controller ?这里有两个不同的上下文。所以,我应该根据租户注入(inject)不同的 ExchangeService。

@Configuration
public class FooTenant{
@Bean
public ExchangeService bar() {
return new ZeroCommisionExchangeService ();
}
}


@Configuration
public class BarTenant{
@Bean
public ExchangeService bar() {
return new StandardCommisionExchangeService ();
}
}

编辑:
我知道我可以获得对 Spring 上下文的引用并“手动”请求服务,但我正在寻找一个更通用的解决方案,这个问题由 IoC 框架解决。

最佳答案

虽然可以在运行时交换在 spring 上下文中实例化的 bean (HotswappableTargetSource),但它并不适用于您的用例。

请记住,您的应用程序有一个 Spring 上下文,所有线程都使用相同的实例(在大多数情况下),这意味着当您交换 bean 实现时,您正在为您的所有应用程序用户有效地执行此操作。为防止这种情况,您会遇到确保线程安全的问题,使用线程局部变量,如另一个答案中所列。

虽然可以继续这种方法并实现完成工作的实现,但这绝对是解决这个问题的一种非常人为的方法。

您应该退后一步,以更健康、系统范围的设计观点来看待您的问题。翻开你的模式书籍,看看如何解决这个问题,不管你是使用 Spring 还是其他框架。上面一些答案中描述的服务定位器、工厂 bean 等是朝着正确方向迈出的一步。

您的用例对于 Multi-Tenancy 应用程序非常常见。您需要根据tenantId 缩小可能会发生变化的事物与不断变化的事物的范围。

例如问题中提到的,每个租户可能有不同的佣金金额,甚至不同的佣金计算算法。一个简单的解决方案是实现 CommissionCalculationService接受 tenantId ,以及任何其他要计算佣金的域对象,我想这将类似于 OrderSale ,在您的应用程序中任何有意义的东西。

您现在需要一个 CommissionServiceFactoryServiceLocator其中将包含 CommissionCalculationService 的租户特定实现. Service Locator在 Spring 上下文加载时实例化,并在应用程序启动时注入(inject)实现类。

当你想为租户计算佣金时,你基本上得到tenantId根据 tenantId,从用户的登录中,将租户 ID 传递给您的服务定位器通过,服务定位器返回服务实现的适当实例。在您的调用类中,使用此实例计算租户的佣金。

另一个要考虑的模式是 Strategy Pattern , 甚至 Template Pattern .

最重要的是,即使您希望干净地实现特定于租户的逻辑,也不要更改上下文中加载的 bean。在您的上下文中拥有可以处理所有租户特定逻辑的类。依靠设计模式从基于租户 id 的上下文中使用正确的 bean。

如果答案有点冗长,我深表歉意,我觉得有必要解释为什么我认为在加载的 Spring Context 中更新 bean 不是合适的解决方案。

关于spring - 如何根据租户在运行时选择spring配置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20207851/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com