Maison  >  Article  >  Java  >  Comment implémenter le mécanisme SPI de SpringBoot

Comment implémenter le mécanisme SPI de SpringBoot

WBOY
WBOYavant
2023-05-16 09:10:11916parcourir

    Introduction

    SPI (Service Provider Interface) est un mécanisme de découverte de services intégré au JDK, qui peut être utilisé pour activer des extensions de framework et des composants de remplacement. Il est principalement utilisé pour le développement dans des frameworks, tels que Dubbo, Spring, et Common-Logging , JDBC, etc. adoptent le mécanisme SPI et utilisent différentes implémentations pour la même interface afin de la fournir à différents utilisateurs, améliorant ainsi l'évolutivité du framework.

    Implémentation Java SPI

    Le SPI intégré de Java analyse le fichier nommé avec le nom complet de l'interface dans le répertoire META-INF/services/ du package classPath et jar via la classe java.util.ServiceLoader, et charge l'interface spécifiée dans le fichier Implémentez la classe pour terminer l'appel.

    Exemples d'instructions

    Créez une interface dynamique

    public interface VedioSPI
    {
        void call();
    }

    Classe d'implémentation 1

    public class Mp3Vedio implements VedioSPI
    {
        @Override
        public void call()
        {
            System.out.println("this is mp3 call");
        }
    }

    Classe d'implémentation 2

    public class Mp4Vedio implements VedioSPI
    {
        @Override
        public void call()
        {
           System.out.println("this is mp4 call");
        }
    }

    Créez un nouveau répertoire META-INF/services/ dans le répertoire source du projet et créez com.skywares.fw. fichiers juc.spi .VedioSPI.

    Comment implémenter le mécanisme SPI de SpringBoot

    Tests associés

    public class VedioSPITest
    {
        public static void main(String[] args)
        {
            ServiceLoader<VedioSPI> serviceLoader =ServiceLoader.load(VedioSPI.class);
            serviceLoader.forEach(t->{
                t.call();
            });
        }
    }

    Description : Java implémente spi via ServiceLoader pour trouver les classes d'outils fournies par le service.

    Résultats d'exécution

    Comment implémenter le mécanisme SPI de SpringBoot

    Analyse du code source

    Ce qui précède n'est qu'un exemple simple pour implémenter la fonction SPI intégrée de Java. Le principe d'implémentation est que ServiceLoader est une classe d'outils Java intégrée pour trouver des interfaces fournissant des services. Il recherche les interfaces fournissant des services en appelant la méthode load(), et enfin parcourt pour accéder aux classes d'implémentation des interfaces fournissant des services une par une. .

    Comment implémenter le mécanisme SPI de SpringBoot

    Vous pouvez trouver dans le code source :

    • La classe ServiceLoader elle-même implémente l'interface Iterable et y implémente la méthode itérateur. L'implémentation de la méthode itérateur appelle la méthode dans la classe interne LazyIterator après l'analyse. le fichier d'interface du fournisseur de services. Le résultat final est renvoyé dans l'itérateur et l'accès direct à la classe d'implémentation d'interface fournie par le service n'est pas pris en charge.

    • Les fichiers correspondants à toutes les interfaces des fournisseurs de services sont placés dans le répertoire META-INF/services/. Le type final détermine que le répertoire PREFIX ne peut pas être modifié.

    Bien que l'idée du mécanisme SPI fourni par Java soit très bonne, elle présente également des inconvénients correspondants. Les détails sont les suivants :

    • Les méthodes intégrées de Java ne peuvent être obtenues que par traversée

    • L'interface du fournisseur de services doit être placée dans le répertoire META-INF/services/.

    Compte tenu des problèmes existant dans le spi de Java, le mécanisme SPI de Spring suit l'idée du SPI, mais l'étend et l'optimise.

    Spring SPI

    Spring SPI suit l'idée de conception de Java SPI Spring utilise spring.factories pour implémenter le mécanisme SPI, qui peut fournir l'évolutivité du framework Spring sans modifier le code source de Spring.

    Exemple Spring

    Interface de définition

    public interface DataBaseSPI
    {
       void getConnection();
    }

    Implémentation associée

    #DB2实现
    public class DB2DataBase implements DataBaseSPI
    {
        @Override
        public void getConnection()
        {
            System.out.println("this database is db2");
        }
    }
    #Mysql实现
    public class MysqlDataBase implements DataBaseSPI
    {
        @Override
        public void getConnection()
        {
           System.out.println("this is mysql database");
        }
    }

    1 Dans le répertoire META-INF du projet, ajoutez le fichier spring.factories

    Comment implémenter le mécanisme SPI de SpringBoot

    2. Remplissez les informations d'interface pertinentes, le contenu. est le suivant

    com.skywares.fw.juc.springspi.DataBaseSPI = com.skywares.fw.juc.springspi.DB2DataBase, com.skywares.fw.juc.springspi.MysqlDataBase

    Description Plusieurs implémentations sont séparées par virgules.

    Classe de test associée

    public class SpringSPITest
    {
        public static void main(String[] args)
        {
             List<DataBaseSPI> dataBaseSPIs =SpringFactoriesLoader.loadFactories(DataBaseSPI.class, 
                     Thread.currentThread().getContextClassLoader());
             for(DataBaseSPI datBaseSPI:dataBaseSPIs){
                datBaseSPI.getConnection();
             }
        }
    }

    Résultats de sortie

    Comment implémenter le mécanisme SPI de SpringBoot

    À partir de l'exemple, nous pouvons voir que Spring utilise spring.factories pour implémenter SPI et que Java implémente SPI. Cependant, la méthode spi de Spring est spécifiquement optimisée pour le spi de Java. est la suivante :

    • Java SPI est un service fournissant une interface correspondant à un fichier de configuration. Le fichier de configuration stocke toutes les classes d'implémentation de l'interface actuelle. Plusieurs interfaces fournissant des services correspondent à plusieurs fichiers de configuration. ;

    • Spring factory SPI est un fichier de configuration spring.factories qui stocke plusieurs interfaces et les classes d'implémentation correspondantes. Le nom complet de l'interface est utilisé comme clé et la classe d'implémentation est utilisée comme valeur à configurer. les classes d'implémentation sont séparées par des virgules, seul spring fabrique un fichier de configuration.

    Alors, comment Spring implémente-t-il SpI en chargeant spring.factories ? Nous pouvons analyser plus en détail via le code source ?

    Analyse du code source

    Comment implémenter le mécanisme SPI de SpringBoot

    Description : loadFactoryNames analyse le nom complet de la classe d'implémentation de l'interface spécifiée dans le fichier spring.factories. L'implémentation spécifique est la suivante :

    Comment implémenter le mécanisme SPI de SpringBoot

    .

    Description : obtenez le chemin du fichier META-INF/spring.factories dans tous les packages jar et renvoyez-le sous forme de valeur d'énumération. Parcourez le chemin du fichier spring.factories, chargez et analysez un par un, intégrez le nom de classe d'implémentation du type factoryClass, obtenez le nom de classe complet de la classe d'implémentation, puis effectuez l'opération d'instance de la classe. comme suit :

    Comment implémenter le mécanisme SPI de SpringBoot

    Explication : L'instanciation est L'initialisation correspondante est obtenue par réflexion.

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Déclaration:
    Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer