我想建立一个可以装载一个插件模块ServiceLoader
。 这需要将文件添加到META-INF/services
目录,即服务接口命名,并包含合格的路径,以实现它的类。 然后,你可以通过调用加载这些服务ServiceLoader.load()
下面是一个例子:
说,我们要提供一个叫做插件接口org.example.plugins.PluginService
。 然后,我们提供了类此服务的实现org.example.plugins.impl.ExamplePlugin
。
如果我们希望有某种插件机制,我们可以创建一个JAR文件,包含实现。 这个JAR文件还必须包含文件META-INF/services/org.example.plugins.PluginService
。 此文件必须包含一行
org.example.plugins.impl.ExamplePlugin
启用ServiceLoader
找到执行。 如果该JAR文件在构建路径,你可以通过调用加载插件
Iterator<PluginService> it = ServiceLoader.load(PluginService.class).iterator();
这个迭代会给你访问过由找到的所有插件ServiceLoader
。
出于某种原因,摇篮不包括文件到META-INF
默认目录。 有没有办法让产生的JAR包含这样的文件?
我已经找到了方法metaInf
类Jar
。 但我不知道常规不够好找到我自己的解决方案。
你把META-INF/services/org.example.plugins.PluginService
中src/main/java
,但它不是一个来源,它是一个资源文件,因此应根据Maven的目录布局约定放在资源文件夹,也就是
src/main/resources/META-INF/services/org.example.plugins.PluginService
在这种情况下,一切都应该工作开箱。
同时,我发现在(有点)解决我的问题类似的问题 。
添加以下到gradle.build
文件,解决了我的问题
jar {
from ('./src/main/java') {
include 'META-INF/services/org.example.plugins.PluginService'
}
}
现在的JAR文件看起来如预期
.
|- org
| `- example
| `- plugins
| `- impl
| `- ExamplePlugin.class
`- META-INF
|- MANIFEST.MF
`- services
`- org.example.plugins.PluginService
希望他们能在jar任务就像蚂蚁确实实现这一点。 有人已经工作就可以了: http://fgaliegue.blogspot.fr/2013/06/gradle-serviceloader-support.html
如果你碰巧继承不遵循Maven的约定一些基于蚂蚁遗留代码,下面可能会有帮助。
定义你的源组,以满足传统的结构,包括像这样的一行:
include 'META-INF/services/**'
在源集。 这种模式是通用的,将拿起您的所有元INF服务。
下面完整的例子。
sourceSets {
main {
java {
srcDir 'src'
exclude '**/Test*.java'
}
resources {
srcDir 'src'
include '**/*.xml'
include 'META-INF/services/**'
}
}
test {
java {
srcDir 'src'
include '**/Test*.java'
}
resources { srcDir 'resources' }
}
}
嗨可以试试这个: https://plugins.gradle.org/plugin/com.github.harbby.gradle.serviceloader
用法
serviceLoader {
serviceInterface 'org.example.plugins.PluginService'
serviceInterface 'org.example.plugins.PluginService2'
}