Proyecto de implementación de SPI uso conectable de la práctica de componentes adicionales del proyecto

        Recientemente, un proyecto necesita almacenar contenido de archivos, el cliente no usa el almacenamiento de objetos predeterminado del producto y el producto no desea integrar código personalizado en el producto, por lo que debe diseñarse como un complemento conectable, y el primer contacto con SPI y SpringBoot Starter. Los dos son muy similares y diferentes, aquí hay un resumen de la implementación de SPI, el siguiente es un ejemplo completo;

        Muchos blogs en Internet tienen todos los códigos en un solo proyecto, lo cual es un inconveniente de entender y usar. Aquí, se divide en 3 proyectos de acuerdo con los escenarios de uso reales; el ejemplo requiere 3 jars; el jar de interfaz, el plug-in jar y el jar comercial; el enlace del código fuente al final del artículo.

El proyecto IDEA es el siguiente: 

1. Escriba el jar de la interfaz : para que lo usen los otros dos jar

 coordenadas pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.idto.spi</groupId>
    <artifactId>idto-spi-api</artifactId>
    <version>1.0</version>
    <description>SPI-接口层jar包</description>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>7</source>
                    <target>7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>

    </dependencies>
</project>

Definir una clase de interfaz Decir

package com.idto.spi;

/**
 * @author idto
 * @title: Say
 * @projectName
 * @description: SPI定义的接口 需要业务层和实现的插件引用
 * @date 2022/2/22 10:40
 */
public interface Say {

    void sayWithLanguage(String language);
}

Compile y empaquete idto-spi-api.jar en el almacén local y utilícelo más tarde.

2. Complemento de escritura SPI -- tarro de complementos

 coordenadas pom, importe el paquete idto-spi-api.jar creado en el paso 1

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.org.bjca</groupId>
    <artifactId>idto-spi-plug</artifactId>
    <version>1.0</version>
    <description>SPI-插件jar包</description>

    <dependencies>
        <!--引入定义的接口-->
        <dependency>
            <groupId>com.idto.spi</groupId>
            <artifactId>idto-spi-api</artifactId>
            <version>1.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>7</source>
                    <target>7</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

Escriba la clase de implementación de la interfaz Digamos que aquí se escriben dos clases de implementación

package com.idto.spi.impl;

import com.idto.spi.Say;


public class America implements Say {

    @Override
    public void sayWithLanguage(String s) {
        System.out.println("Speak English -->"+s);
    }
}


package com.idto.spi.impl;

import com.idto.spi.Say;


public class China implements Say {
    @Override
    public void sayWithLanguage(String s) {
        System.out.println("中文说-->"+s);
    }
}

enfocar  

Cree un nuevo META-INF.services en recursos y luego cree un nuevo archivo com.idto.spi.Say (ruta completa de la interfaz) en services.com.idto.spi.Say escribe la descripción completa de la clase de implementación en ser usado en el archivo.ruta, múltiples clases de implementación están escritas en líneas

 Compile y empaquete idto-spi-plug.jar en el almacén local y utilícelo más tarde.

Ahora que se completó la implementación de SPI, ¡veamos cómo usarlo!

 3. Escribir código comercial -- tarro comercial

 coordenadas pom, importe el paquete idto-spi-api.jar creado en el paso 1

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.org.bjca</groupId>
    <artifactId>idto-spi-business</artifactId>
    <version>1.0</version>
    <description>SPI-业务jar包</description>

    <dependencies>
        <!--引入定义的接口-->
        <dependency>
            <groupId>com.idto.spi</groupId>
            <artifactId>idto-spi-api</artifactId>
            <version>1.0</version>
        </dependency>
    </dependencies>

    <build>
        <resources>
            <resource>
                <directory>src/main/resource</directory>
                <includes>
                    <include>*</include>
                </includes>
            </resource>
        </resources>

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.1.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <!-- 设置主类  -->
                                    <mainClass>com.idto.spi.Main</mainClass>
                                </transformer>
                            </transformers>
                            <filters>
                                <filter>
                                    <artifact>*:*</artifact>
                                    <!-- 打包时过滤无用的文件,不打包进jar -->
                                    <excludes>
                                        <exclude>META-INF/*.SF</exclude>
                                        <exclude>META-INF/*.DSA</exclude>
                                        <exclude>META-INF/*.RSA</exclude>
                                    </excludes>
                                </filter>
                                <filter>
                                    <artifact>junit:junit</artifact>
                                    <includes>
                                        <include>junit/framework/**</include>
                                        <include>org/junit/**</include>
                                    </includes>
                                    <excludes>
                                        <exclude>org/junit/experimental/**</exclude>
                                        <exclude>org/junit/runners/**</exclude>
                                    </excludes>
                                </filter>
                            </filters>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Escriba el método de llamada de SPI y cargue el complemento a través del ServiceLoader que viene con java, especifique el directorio del complemento en el código, preferiblemente fuera del jar del proyecto, que es conveniente para conectar y desconectar. El complemento está escrito en el código solo como referencia.

package com.idto.spi;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ServiceLoader;


/**
 * @author idto
 * @title: Main
 * @projectName idto-spi-business
 * @description:  SPI调用例子
 * @date 2022/2/22 13:02
 */
public class Main {
    public static void main(String[] args) throws MalformedURLException {
        // 获取插件的路径
        String projectPath = System.getProperty("user.dir");
        Path path = Paths.get(projectPath);
        String plugPath = path.toString() + File.separator + "plugs";
        String location = plugPath + File.separator + "idto-spi-plug-1.0.jar";
        System.out.println("plug Path is -->" + location);
        System.out.println( );
        System.out.println( );

        System.out.println("---start---");
        URL url = new File(location).toURI().toURL();
        URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{url}, ClassLoader.getSystemClassLoader());
        ServiceLoader<Say> says = ServiceLoader.load(Say.class, urlClassLoader);
        for (Say say : says) {
            say.sayWithLanguage("Hello World!");
        }
        System.out.println("---end---");
    }
}

En este punto, puede probar directamente en el código;

Para simular el escenario de uso real, empaquetamos y compilamos, y copiamos el idto-spi-business-1.0.jar escrito en un directorio de prueba para realizar pruebas;

Escenario de prueba 1: sin complementos

 No se encuentra la clase de implementación correspondiente y la impresión está vacía

Escenario de prueba 1: coloque el complemento de acuerdo con el directorio especificado

Coloque idto-spi-plug-1.0.jar en D:\log\plugs

 Ejecute el código de clase empresarial y el resultado es que los métodos de las dos clases de implementación se ejecutan correctamente, de la siguiente manera:

Dirección del código fuente: https://gitee.com/idtolerate/idto-spi-demo

No es fácil ser original. Si es útil para usted, puede hacer clic en Me gusta y recopilar (#^.^#)

Supongo que te gusta

Origin blog.csdn.net/idto315/article/details/123065676
Recomendado
Clasificación