我可以让类加载器动态查找Java类吗



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

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

我有一个tomcat应用程序,它目前正在使用OpenJDK 8。

我相信我可以编写一个自定义的ClassLoader,它可以操纵类路径,以基于ThreadLocal的不同方式选择C的定义。但是我担心结果会被缓存在JVM代码缓存之类的地方。除非我也能覆盖这种行为,否则下次需要该类时,运行时条件可能已经更改,缓存中的版本可能会出错。

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

好吧,简单的解决方案是NOT有多个类C的定义,但有"类C1"、"类C2"等(即它们不重叠,可以同时加载(,然后您的运行时属性会根据需要选择正确的一个。这是最简单的解决方案,所以请先考虑一下。但它可能无法满足您的需求。

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

实现您想要的操作的干净方法是将C定义为接口,然后您可以加载并使用任何实现接口C 的类

最新更新