我想根据运行时条件动态地选择不同的类实现。假设我有一个完全限定类名为c的类。我运行的系统可能有许多c类的定义,每个定义都在自己的jar中。我有一个运行时条件(保存在threadlocal中),它告诉我们应该选择哪个定义。
我在评论中被要求澄清最初的要求,所以我会尽我所能澄清要求。有多个团队编写软件来为这个系统做出贡献,比如在许多独立模块中有4000个类。更重要的是,他们可以随着时间的推移而改变。它们目前运行在不同的jvm中,因此类重叠没有问题。现在我们考虑在同一个jvm中运行它们,同时在同一个jvm上运行多个版本;所使用的具体实现集由threadlocal区分。因此,最初的问题是如何允许线程一次运行一组实现,另一次运行另一组实现。
我有一个tomcat应用程序,目前正在使用openjdk8。
我相信我可以编写一个定制的类加载器来操纵类路径,从而根据threadlocal选择不同的c定义。但我担心结果会被缓存在jvm代码缓存之类的地方。除非我也可以重写该行为,否则下次需要该类时,运行时条件可能已经更改,并且缓存中的版本将是错误的。
有什么办法可以做我该做的吗?
2条答案
按热度按时间k2arahey1#
好吧,简单的解决方案是不要有多个类c的定义,而是有“类c1”、“类c2”等(也就是说,它们不重叠,可以同时加载),然后运行时属性根据需要选择正确的定义。这是最简单的解决方法,所以首先要考虑它。但它可能不能满足你的需要。
如果您真的需要一个“类c”有多个独立的实现,那么您实际上谈论的是一个“热插拔”场景。幸运的是,tomcat和其他工具在很久以前的热交换方面做得很好(有局限性)。您可能已经知道这一点,但是“热交换”满足了开发人员的需求,开发人员编写“c类”代码,将其部署到容器中,进行尝试,意识到它有问题,进行快速代码编辑,并希望在不重新启动容器的情况下运行修改后的代码。热交换通过基本上覆盖jvm中的新实现来实现这一点。它只在一定程度上起作用,因为每次“重新部署”都会污染jvm的“类空间”,最终会运行“类空间内存”和/或jvm开始变得不稳定。不过,根据您的需求和容忍度,热交换可能会奏效。
z2acfund2#
做您想做的事情的干净方法是将c定义为一个接口,然后您可以加载和使用实现接口c的任何类