Maison  >  Article  >  Java  >  Une brève introduction au mécanisme Java spi

Une brève introduction au mécanisme Java spi

黄舟
黄舟original
2017-03-15 11:27:281642parcourir

Récemment, j'ai constaté que certains des frameworks de l'entreprise et certains des frameworks open source que j'ai vus auparavant utilisent le mécanisme SPI de Java pour la découverte et l'accès à certains services.

Résumez donc brièvement l'idée du mécanisme Java spi.

Il existe souvent de nombreuses solutions d'implémentation différentes pour chaque module abstrait de notre système, telles que la solution du module de journalisation, le module d'analyse xml, la solution du module jdbc, etc. Dans la conception orientée objet, nous recommandons généralement que les modules soient programmés en fonction de l'interface , et les classes d'implémentation ne doivent pas être codées en dur entre les modules. Une fois qu'une classe d'implémentation spécifique est impliquée dans le code, elle viole le principe de pluggabilité. Si une implémentation doit être remplacée, le code doit être modifié.

Afin de réaliser que le module peut être assemblé sans le spécifier dynamiquement dans le programme, un mécanisme de découverte de service est nécessaire. Java SPI fournit un tel mécanisme : un mécanisme permettant de rechercher des implémentations de services pour une certaine interface. C'est un peu similaire à l'idée d'​​IOC, qui est de déplacer le contrôle de l'assemblage en dehors du programme. Ce mécanisme est particulièrement important dans la conception modulaire.

L'accord spécifique de java spi est le suivant :

Lorsque le prestataire fournit une implémentation de l'interface de service, dans le META-INF/services du jar package Un fichier nommé d'après l'interface de service est également créé dans le répertoire /. Ce fichier contient la classe d'implémentation spécifique qui implémente l'interface de service. Lorsqu'un programme externe assemble ce module, il peut trouver le nom de classe d'implémentation spécifique via le fichier de configuration dans le package jar META-INF/services/, et charger l'instanciation pour terminer l'injection du module.

Sur la base d'une telle convention, vous pouvez facilement trouver la classe d'implémentation de l'interface de service sans avoir à la spécifier dans le code.

jdk fournit une classe d'outils pour la recherche d'implémentation de service : java.util.ServiceLoader

Exemple

1.common-logging

La première interface de façade de journalisation fournie par Apache. Seule interface, pas d'implémentation. La solution spécifique est implémentée par chaque fournisseur. On constate que le fournisseur de journaux analyse le fichier de configuration META-INF/services/org.apache.commons.logging. Retrouvez le contenu du log mentionnant la classe d'implémentation industrielle et commerciale. Tant que notre implémentation de journal inclut ce fichier et formule la classe d'implémentation de l'interface d'usine LogFactory dans le fichier. 2.jdbcAvant jdbc4.0, les développeurs devaient également s'appuyer sur

Class

. forName("xxx") pour charger le

driver

jdbc4 découvre également le fournisseur de pilotes basé sur le mécanisme spi. Vous pouvez utiliser le META-INF/services/java.sql. Fichier de pilote Il existe un moyen de spécifier la classe d'implémentation pour exposer le fournisseur de pilotes. 3. Écrivez vous-même un exemple simple Supposons qu'il existe un système de

recherche

de contenu, qui est divisé en deux modules : l'affichage et la recherche. L'affichage et la recherche sont basés sur la programmation de l'interface. La mise en œuvre de la recherche peut être basée sur une recherche du système de fichiers ou une recherche basée sur une base de données. L'exemple de code est le suivant

Search.java : Interface de recherche

Fichier

Search.java : Implémentation de la recherche du système de fichiers

package search;  
  
import java.util.List;  
  
import definition.Doc;  
  
public interface Search {  
    List<Doc> search(String keyword);  
}

DatabaseSearch.java

package search;  
  
import java.util.List;  
  
import definition.Doc;  
  
public class FileSearch implements Search {  
  
    @Override  
    public List<Doc> search(String keyword) {  
        System.out.println("now use file system search. keyword:" + keyword);  
        return null;  
    }  
  
}

SearchTest.java

package search;  
  
import java.util.List;  
  
import definition.Doc;  
  
public class DatabaseSearch implements Search {  
  
    @Override  
    public List<Doc> search(String keyword) {  
        System.out.println("now use database search. keyword:" + keyword);  
        return null;  
    }  
  
}
Enfin créé en META-INF/ services/recherche.Rechercher un fichier.

Lorsque le contenu du fichier search.Search est "search.FileSearch", le résultat du programme est :

package search;  
  
import java.util.Iterator;  
import java.util.ServiceLoader;  
  
public class SearchTest {  
  
    public static void main(String[] args) {  
        ServiceLoader<Search> s = ServiceLoader.load(Search.class);  
        Iterator<Search> searchs = s.iterator();  
        if (searchs.hasNext()) {  
            Search curSearch = searchs.next();  
            curSearch.search("test");  
        }  
    }  
}
Lorsque le contenu du fichier search.Search est "search.DatabaseSearch", le programme le résultat est :

On peut voir que SearchTest n'a aucun code lié à l'implémentation spécifique, mais est basé sur le mécanisme spi pour trouver l'implémentation du service
now use file system search. keyword:test

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:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn