繁体   English   中英

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

[英]Can I have a classloader find Java classes dynamically?

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

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

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM