First, take a look at the overall structure:
In the main of src, we define a path such as com.lf. There are two packages below. First, let's look at the API package. We define an interface MyPrinterAPI:
package com.lf; import com.lf.API.MyPrinterAPI; import java.util.ServiceLoader; public class testClient { public static void main(String[] args) { ServiceLoader<MyPrinterAPI> printers = ServiceLoader.load(MyPrinterAPI.class); // System.out.println(printers); for (MyPrinterAPI printer : printers) { printer.sayHello("SPI"); } } }
Then, under the impl package, we define two implementations of this interface - MyPrinterA and MyPrinterB (C is a comparison, but does not implement the interface). The code is as follows:
// MyPrinterA.java package com.lf.impl; import com.lf.API.MyPrinterAPI; public class MyPrinterA implements MyPrinterAPI { @Override public String sayHello(String str) { String res = "This is printer A!\nHello " + str; System.out.println(res); return res; } }
// MyPrinterB.java package com.lf.impl; import com.lf.API.MyPrinterAPI; public class MyPrinterB implements MyPrinterAPI { @Override public String sayHello(String str) { String res = "This is printer B!\nHello " + str; System.out.println(res); return res; } }
After completing these three java files, we create a folder path such as META-INF/services under the resources folder, and then create a file com.lf.API.MyPrinterAPI under the services folder. You can see that this file is the fully qualified name of our defined interface MyPrinterAPI.
After that, we write:
com.lf.impl.MyPrinterA com.lf.impl.MyPrinterB
(in the above figure, my IDE prompts A and B when I write, but there is no C, because C does not implement the interface.)
After the above steps are completed, we can start our test.
We create a test file testClient under com.lf, in which we write the main function as the test entry:
// testClient.java package com.lf; import com.lf.API.MyPrinterAPI; import java.util.ServiceLoader; public class testClient { public static void main(String[] args) { ServiceLoader<MyPrinterAPI> printers = ServiceLoader.load(MyPrinterAPI.class); for (MyPrinterAPI printer : printers) { printer.sayHello("SPI"); } } }
Operation result:
This is printer A! Hello SPI This is printer B! Hello SPI
You can see that the two implementation classes we wrote were called successfully.