使用位置创建一个新的源文件夹,然后在其中创建文件夹并放入完全限定的类名 (FQCN) 文件。这应该会自动将它们复制到jar文件中。因此,对于 FQCN 为 的接口的实现,您将拥有:src/main/resources
META-INF/services
com.acme.MyInterface
Project
| src
| | main
| | java
| | [your source code]
| | resources
| | META-INF
| | services
| | com.acme.MyInterface
请注意,这是文件的名称,而不是像 Java 包那样的目录结构。该文件的名称是要实现的接口的 FQCN,在其中,每个实现的 FQCN 将在其自己的行上,例如:com.acme.MyInterface
com.example.MyInterfaceImpl
com.example.AnotherMyInterfaceImpl
值得注意的是,这也适用于具有默认源代码集的 Gradle 项目。
完成此操作后,您可以使用以下命令加载接口的所有实现:ServiceLoader
ServiceLoader<MyInterface> loader = ServiceLoader.load(MyInterface.class);
for (MyInterface service : loader) {
// Prints com.example.MyInterfaceImpl and com.example.AnotherMyInterfaceImpl
System.out.println(service.class.getName());
}
需要注意的一些事项:
- 所有实现都必须具有无参数构造函数
- 使用模块或自定义类装入器的应用程序可能必须使用
ServiceLoader.load
如果这些条件对您不起作用,那么您可能需要切换到另一个系统,例如CDI风格的框架,如Spring,EJB等。