Java服务如何提供应该工作的API?
题
似乎每个人都有一个不愉快的刷子 Java服务提供商, ,您可以使用名为Meta-Inf/services/com.example.interface的文件来完成的事情,但是除了尝试加载右XML Parser外,没有人使用。我正在尝试与使用服务提供商API的库一起工作,并欺骗它,以便我可以提供一些运行时扩展的类(使用CGLIB),这些类实际上并未实现界面,但可以轻松地进行操作。
基本上,我认为我需要执行的步骤是:
- 创建一个自定义类加载程序,该加载程序将响应getResources(...)并返回“额外” URL
- 当询问“额外”资源时
- 最后,让该类加载程序在要求时加载这些类
但这是我迷路的地方。例如,当库试图确定哪些实施者在那里时,它调用返回一堆URL的GetResources(...)。但是getResourceasStream(...)不采用URL,而是“名称”。名称似乎是阶级路径相关的,因此到处都是相同的。因此,meta-inf/services/com.example.interface in in jar中的meta-inf/services/com.example.interface具有相同的“名称”,对吗?除了以某种方式与那些爆炸的XML解析器一起使用...
当然,所有这些都假定它们足够聪明/善良,可以调用classLoader.getSystemClassLoader()而不是使用classLoader.getSystemsources(...),classloader.getSystemstemtemresourceasStream(...)等,如后一种情况。无法连接classloader并提供伪造的文件。
我想在那种情况下,当我的代码被Maven打包时,我可以使用BCEL来操纵类文件,而不是等到运行时间与CGLIB进行操作?
解决方案
我描述的想法是正确的轨道。我犯的错误是在想使用 ClassLoader.getResourceAsStream(..)
访问URL的内容。相反,你应该只是 URL.openStream()
.
我在发布之前找到了它, java.util.ServiceLoader
(@since 1.6)提供了一些有关如何正确做事的见解。