Examples of using SPI in Java

Keywords: Java

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.

Posted by darf on Sat, 26 Oct 2019 12:55:49 -0700