[Deep shallow-JVM] (77): SPI

Keywords: Java jvm

concept

Service Provider Interface

rule

  1. Create a file named after the fully qualified interface name in resource/META-INF/services, and implement the fully qualified name of the class in the content
  2. Interface Implementation Class in classpath Path
  3. The main program loads the implementation module dynamically through java.util.Service Loader (scan the configuration file in META-INF/services directory to find the implementation class and load it into JVM)

benefit

Decoupling, there is no hard coding between the main program and the implementation class.

Example

package com.mousycoder.mycode.thinking_in_jvm;

/**
 * @version 1.0
 * @author: mousycoder
 * @date: 2019-09-16 16:14
 */
public interface SPIService {
    void execute();
}
package com.mousycoder.mycode.thinking_in_jvm;

/**
 * @version 1.0
 * @author: mousycoder
 * @date: 2019-09-16 16:16
 */
public class SpiImpl1 implements SPIService {
    @Override
    public void execute() {
        System.out.println("SpiImpl1.execute()");
    }
}
package com.mousycoder.mycode.thinking_in_jvm;

/**
 * @version 1.0
 * @author: mousycoder
 * @date: 2019-09-16 16:16
 */
public class SpiImpl2 implements SPIService {
    @Override
    public void execute() {
        System.out.println("SpiImpl2.execute()");
    }
}

Create a file named com.mousycoder.mycode.thinking_in_jvm.SPIService under resources/META-INF/services/directory with the content
com.mousycoder.mycode.thinking_in_jvm.SpiImpl1
com.mousycoder.mycode.thinking_in_jvm.SpiImpl2

main program

package com.mousycoder.mycode.thinking_in_jvm;

import sun.misc.Service;

import java.util.Iterator;
import java.util.ServiceLoader;

/**
 * @version 1.0
 * @author: mousycoder
 * @date: 2019-09-16 16:21
 */
public class SPIMain {

    public static void main(String[] args) {
        Iterator<SPIService> providers = Service.providers(SPIService.class);
        ServiceLoader<SPIService> load = ServiceLoader.load(SPIService.class);

        while (providers.hasNext()){
            SPIService ser = providers.next();
            ser.execute();
        }

        System.out.println("-----------------------");
        Iterator<SPIService> iterator = load.iterator();
        while (iterator.hasNext()){
            SPIService ser = iterator.next();
            ser.execute();
        }
    }
}

output

SpiImpl1.execute()
SpiImpl2.execute()
-----------------------
SpiImpl1.execute()
SpiImpl2.execute()

Posted by charlestide on Tue, 01 Oct 2019 16:27:35 -0700