0

我想根据运行时条件动态选择不同的类实现。假设我有一个具有完全限定类名称 C 的类。我正在运行的系统可能有许多 C 类的定义,每个定义都在自己的 jar 中。我有一个运行时条件(保存在 ThreadLocal 中),它告诉应该选择哪个定义。

有人在评论中要求我澄清原始要求,因此我将尽我所能澄清要求。有多个团队编写软件来为这个系统做出贡献——就像许多独立模块中的 4000 个类一样。更重要的是,它们可以随着时间而改变。它们目前在单独的 JVM 中运行,因此类重叠没有问题。现在我们正在考虑在同一个 JVM 中运行它们,同时在同一个 JVM 上运行多个版本;使用哪个特定的实现集由 ThreadLocal 区分。所以最初的问题是如何允许一个线程一次运行一组实现,另一次运行另一个。

我有一个当前使用 OpenJDK 8 的 tomcat 应用程序。

我相信我可以编写一个自定义的 ClassLoader 来操纵类路径以根据 ThreadLocal 以不同的方式选择 C ​​的定义。但我担心结果会被缓存在某个地方,比如 JVM Code Cache。除非我也可以覆盖该行为,否则下次需要该类时,运行时条件可能已更改并且缓存中的版本将是错误的。

有什么办法可以做我需要做的吗?

4

2 回答 2

1

好吧,简单的解决方案是不要有多个 C 类定义,而是有 'class C1'、'class C2' 等(即它们不重叠并且可以同时加载),然后你的运行时属性只是选择合适的那个。这是最简单的解决方案,因此请先考虑一下。但它可能无法满足您的需求。

如果您确实需要对单个“C 类”进行多个单独的实现,那么您实际上在谈论的是“热插拔”场景。幸运的是,Tomcat 和其他工具在热交换方面做得很好(有限制)。您可能已经知道这一点,但“热插拔”满足了编写“C 类”代码、将其部署到容器、进行尝试、意识到它有故障、进行快速代码编辑并想要运行修改代码而不重新启动容器。热交换通过基本上覆盖 JVM 中的新实现来做到这一点。它只能在一定程度上起作用,因为每次“重新部署”都会污染 JVM 的“类空间”,并且最终会耗尽“类空间内存”和/或 JVM 开始变得不稳定。

于 2020-12-06T07:17:11.973 回答
1

做你想做的事情的干净方法是将C定义为接口,然后你可以加载和使用任何实现接口C的类

于 2020-12-06T07:21:54.717 回答