Java服务提供API应该如何工作?

Java服务提供API应该如何工作?,java,service,provider,cglib,bcel,Java,Service,Provider,Cglib,Bcel,似乎每个人都有过不愉快的经历,你可以用一个名为META-INF/services/com.example.Interface的文件来做这件事,但是除了尝试加载正确的XML解析器之外,没有人使用它。我正在尝试使用一个使用服务提供者API的库,并对它进行欺骗,这样我就可以提供一些运行时扩展类(使用cglib),这些类实际上并没有实现接口,但可以很容易地实现 基本上,我认为我需要执行的步骤是: 创建一个自定义类加载器,该加载器将响应getResources(…),并返回一个“额外”URL 还有一个类加

似乎每个人都有过不愉快的经历,你可以用一个名为META-INF/services/com.example.Interface的文件来做这件事,但是除了尝试加载正确的XML解析器之外,没有人使用它。我正在尝试使用一个使用服务提供者API的库,并对它进行欺骗,这样我就可以提供一些运行时扩展类(使用cglib),这些类实际上并没有实现接口,但可以很容易地实现

基本上,我认为我需要执行的步骤是:
  • 创建一个自定义类加载器,该加载器将响应getResources(…),并返回一个“额外”URL
  • 还有一个类加载器钩子getResourceAsStream(…),在请求“额外”资源时,返回我将使用cglib操作的类的列表
  • 最后,让类加载器在请求时加载这些类
  • 但这是我迷路的地方。例如,当库试图确定存在哪些实现者时,它调用getResources(…),返回一组URL。但是getResourceAsStream(…)不接受URL,它接受“名称”。似乎是类路径相关的名称,因此在任何地方都是相同的。所以META-INF/services/com.example.Interface in与JAR中的META-INF/services/com.example.Interface具有相同的“名称”,对吗?但不知怎的,这对那些该死的XML解析器是有效的

    当然,所有这些都假设他们足够聪明/善良,可以调用ClassLoader.getSystemClassLoader(),而不是使用ClassLoader.getSystemResources(…)、ClassLoader.GetSystemResourcesStream(…)等,因为在后一种情况下,无法钩住ClassLoader并提供伪造文件


    我想在这种情况下,当我的代码由Maven打包时,我可以使用BCEL来操作类文件,而不是等到运行时才使用cglib来操作?

    我描述的想法是正确的。我犯的错误是认为使用
    ClassLoader.getResourceAsStream(..)
    访问URL的内容。相反,您应该只使用
    URL.openStream()


    如果我在发布之前找到了它,(@since 1.6)提供了一些关于如何正确操作的见解。

    您是否可以编译一些存根,并以通常的方式通过META-INF/services注册它们,但一旦加载它们,就用cglib代理它们?实际的问题/问题是什么?使用自定义类加载器(并将其设置为调用getResources的库的上下文类加载器…)的方法应该有效。bMail-最终的问题是,我有一些类(
    Type1
    Type2
    ,…)可以由另一个类(
    Runner
    )运行,它们本身在GUI中运行。由于各种原因,这在我的应用程序中是丑陋的。我想做的是动态地将它们“融合”在一起,并将
    Runner$Type1
    Runner$Type2
    等呈现给GUI,以便用户知道哪些类可用。