好像每个人都有Java Service Provider的令人不快的画笔,你可以用一个名为META-INF / services / com.example.Interface的文件来做,但除了试图加载正确的XML解析器。我正在尝试使用一个使用服务提供程序API的库,并欺骗它,以便我可以提供一些运行时扩展类(使用cglib),这些类实际上不实现接口,但可以轻松地实现。
基本上,我认为我需要执行的步骤是:
但这是我迷路的地方。例如,当库试图确定哪些实现者在那里时,它调用getResources(...),它返回一堆URL。但是getResourceAsStream(...)不接受URL,它需要“名称”。名称似乎是类路径相关的,因此到处都是相同的。所以META-INF / services / com.example.Interface在它们的JAR中与META-INF / services / com.example.Interface具有相同的“名称”,对吧?除了某种方式,这适用于那些爆破的XML解析器......
当然,所有这些都假设他们聪明/善良,足以调用ClassLoader.getSystemClassLoader()而不是使用ClassLoader.getSystemResources(...),ClassLoader.getSystemResourceAsStream(...)等,如后一种情况,没有办法挂钩ClassLoader并提供伪造的文件。
我想在这种情况下,当我的代码由Maven打包时,我可以使用BCEL来操作类文件,而不是等到运行时用cglib来完成它?
答案 0 :(得分:3)
我所描述的想法是沿着正确的轨道前进的。我犯的错误是认为使用ClassLoader.getResourceAsStream(..)
来访问URL的内容。相反,你应该URL.openStream()
。
如果我在发布之前找到它,java.util.ServiceLoader
(@since 1.6)提供了一些如何正确处理事情的见解。