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.
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
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
driverjdbc4 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
recherchede 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
FichierSearch.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); }
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!