web-dev-qa-db-fra.com

Différence entre SPI et API?

Quelle est la différence entre interface de fournisseur de service (SPI) et interface de programmation d'application (API) ?

Plus précisément, pour Java bibliothèques, qu'est-ce qui en fait une API et/ou SPI?

292
kctang
  • L’API est la description des classes/interfaces/méthodes/... que vous appelez et utilisez pour atteindre un objectif, et
  • le SPI est la description des classes/interfaces/méthodes/... que vous étendez et implémentiez pour atteindre un objectif.

Autrement dit, l'API vous indique ce qu'une classe/méthode spécifique fait pour vous, et le SPI vous indique ce que vous devez faire pour vous conformer.

Généralement, API et SPI sont séparés. Par exemple, dans JDBC la classe Driver fait partie du SPI: si vous voulez simplement utiliser JDBC, vous n'avez pas besoin de l'utiliser directement, mais toutes les personnes qui implémentent un pilote JDBC doit implémenter cette classe.

Parfois, ils se chevauchent, cependant. L’interface Connection est à la fois SPI et à l’API: vous l’utilisez régulièrement utilisez un pilote JDBC qui doit être implémenté par le développeur du pilote JDBC.

364
Joachim Sauer

De Effective Java, 2nd Edition:

Une infrastructure de fournisseur de services est un système dans lequel plusieurs fournisseurs de services implémentent un service, et le système met les implémentations à la disposition de ses clients, les dissociant des implémentations.

Un cadre de fournisseur de services comprend trois composants essentiels: une interface de service que les fournisseurs mettent en œuvre; une API d'enregistrement de fournisseur, que le système utilise pour enregistrer les implémentations, en donnant aux clients un accès à celles-ci; et une API d'accès au service, que les clients utilisent pour obtenir une instance du service. L’API d’accès au service autorise généralement, mais n’exige pas, le client à spécifier certains critères pour choisir un fournisseur. En l'absence d'une telle spécification, l'API renvoie une instance d'une implémentation par défaut. L'API d'accès au service est la "fabrique statique flexible" qui constitue la base du cadre du fournisseur de services.

Un quatrième composant facultatif d'une structure de fournisseur de service est une interface de fournisseur de service que les fournisseurs implémentent pour créer des instances de leur implémentation de service. En l'absence d'une interface de fournisseur de services, les implémentations sont enregistrées par nom de classe et instanciées de manière réflexive (élément 53). Dans le cas de JDBC, Connection joue le rôle de l'interface de service, DriverManager.registerDriver est l'API d'enregistrement du fournisseur, DriverManager.getConnection est l'API d'accès au service et Pilote est l'interface du fournisseur de services.

Il existe de nombreuses variantes du modèle de structure de fournisseur de services. Par exemple, l'API d'accès au service peut renvoyer une interface de service plus riche que celle requise du fournisseur, à l'aide du modèle d'adaptateur [Gamma95, p. 139]. Voici une implémentation simple avec une interface fournisseur de services et un fournisseur par défaut:

// Service provider framework sketch

// Service interface
public interface Service {
    ... // Service-specific methods go here
}

// Service provider interface
public interface Provider {
    Service newService();
}

// Noninstantiable class for service registration and access
public class Services {
    private Services() { }  // Prevents instantiation (Item 4)

    // Maps service names to services
    private static final Map<String, Provider> providers =
        new ConcurrentHashMap<String, Provider>();
    public static final String DEFAULT_PROVIDER_NAME = "<def>";

    // Provider registration API
    public static void registerDefaultProvider(Provider p) {
        registerProvider(DEFAULT_PROVIDER_NAME, p);
    }
    public static void registerProvider(String name, Provider p){
        providers.put(name, p);
    }

    // Service access API
    public static Service newInstance() {
        return newInstance(DEFAULT_PROVIDER_NAME);
    }
    public static Service newInstance(String name) {
        Provider p = providers.get(name);
        if (p == null)
            throw new IllegalArgumentException(
                "No provider registered with name: " + name);
        return p.newService();
    }
}
53
Roman

API signifie Application Programming Interface, où API est un moyen d'accéder à un service/une fonction fournie par un logiciel ou une plateforme.

SPI signifie Interface avec le fournisseur de services, où SPI est le moyen d'injecter, d'étendre ou de modifier le comportement d'un logiciel ou d'une plate-forme.

L'API est normalement la cible des clients pour accéder à un service et possède les propriétés suivantes:

-> L'API est un moyen programmatique d'accéder à un service pour obtenir un comportement ou un résultat donné.

-> Du point de vue de l'évolution de l'API, l'addition ne pose aucun problème pour les clients

-> Mais les API, une fois utilisées par les clients, ne peuvent pas (et ne devraient pas) être modifiées/supprimées, sauf en cas de communication appropriée, car il s'agit d'une dégradation complète des attentes du client.

Les SPI, d’autre part, sont destinés aux fournisseurs et possèdent les propriétés suivantes:

-> SPI est un moyen d'étendre/modifier le comportement d'un logiciel ou d'une plate-forme (programmable ou programmatique)

-> L’évolution de SPI est différente de celle de l’API, le retrait de SPI n’est pas un problème

-> L'ajout d'interfaces SPI posera des problèmes et risque d'endommager les implémentations existantes.

Pour plus d'explications, cliquez ici: Interface du fournisseur de service

20

La différence entre API et SPI survient lorsqu'une API fournit en outre des implémentations concrètes. Dans ce cas, le fournisseur de service doit implémenter quelques API (appelées SPI)

JNDI en est un exemple:

JNDI fournit des interfaces et des classes pour la recherche de contexte. Le moyen par défaut de rechercher un contexte est fourni dans IntialContext. Cette classe utilisera en interne les interfaces SPI (à l'aide de NamingManager) pour les implémentations spécifiques au fournisseur.

Voir l'architecture JNDI ci-dessous pour une meilleure compréhension.

Enter image description here

18
Sandeep Jindal

FAQ de NetBeans: Qu'est-ce qu'un SPI? En quoi est-il différent d'une API?

API est un terme général - un acronyme pour Application Programming Interface - il signifie quelque chose (en Java, généralement de certaines classes Java) qu'un logiciel expose, ce qui permet à d'autres logiciels de communiquer avec lui.

SPI signifie Interface du fournisseur de service. C'est un sous-ensemble de tout ce qui peut être une API spécifique aux situations dans lesquelles une bibliothèque fournit des classes appelées par l'application (ou la bibliothèque d'API) et qui modifient généralement les tâches que l'application est capable de faire.

L'exemple classique est JavaMail. Son API a deux côtés:

  • Le côté API - que vous appelez si vous écrivez un client de messagerie ou voulez lire une boîte aux lettres
  • Le côté SPI si vous fournissez un gestionnaire de protocole filaire permettant à JavaMail de communiquer avec un nouveau type de serveur, tel qu'un serveur de nouvelles ou un serveur IMAP.

Les utilisateurs de l'API ont rarement besoin de voir ou de parler aux classes SPI, et inversement.

Dans NetBeans, lorsque vous voyez le terme SPI, il s’agit généralement de classes qu’un module peut injecter au moment de l’exécution, ce qui permet à NetBeans de faire de nouvelles choses. Par exemple, il existe un SPI général pour la mise en œuvre de systèmes de contrôle de version. Différents modules fournissent des implémentations de ce SPI pour les systèmes de contrôle de révision CVS, Subversion, Mercurial et autres. Cependant, le code qui traite des fichiers (côté API) n'a pas besoin de savoir s'il existe un système de contrôle de version ou de quoi il s'agit.

11
Ondra Žižka

L'interface du fournisseur de service est l'interface de service que tous les fournisseurs doivent implémenter. Si aucune des implémentations de fournisseur existantes ne fonctionne pour vous, vous devez écrire votre propre fournisseur de service (implémenter l'interface de service) et vous enregistrer quelque part (voir l'article utile de Roman).

Si vous réutilisez l'implémentation existante du fournisseur de l'interface de service, vous utilisez essentiellement l'API de ce fournisseur particulier, qui inclut toutes les méthodes de l'interface de service, ainsi que quelques méthodes publiques. Si vous utilisez des méthodes d'API fournisseur en dehors de l'interface SPI, vous utilisez des fonctionnalités spécifiques au fournisseur.

4
tapasvi

Je suppose qu'un SPI s'insère dans un système plus grand en implémentant certaines fonctionnalités d'une API, puis s'enregistre comme étant disponible via des mécanismes de recherche de service. Une API est utilisée directement par le code de l'application de l'utilisateur final, mais peut intégrer des composants SPI. C'est la différence entre encapsulation et utilisation directe.

4
Chris Dennett

Il y a un aspect qui ne semble pas être mis en évidence mais qui est très important pour comprendre le raisonnement qui sous-tend l'existence de la scission API/SPI.

Le fractionnement API/SPI est requis uniquement lorsque la plate-forme est appelée à évoluer. Si vous écrivez une API et "connaissez" elle a gagné N'ayant besoin d'aucune amélioration future, il n'y a pas vraiment de raison de scinder votre code en deux parties (à part la conception d'objets propres).

Mais ce n'est presque jamais le cas et les utilisateurs doivent avoir la liberté de faire évoluer les API en fonction des besoins futurs, de manière compatible avec les versions antérieures.

Notez que tout ce qui précède suppose que vous construisez une plate-forme que d'autres personnes utilisent et/ou développent et non votre propre API où vous avez tout le code client sous contrôle et vous pouvez donc refactoriser à votre guise.

Permet de l'afficher sur l'un des Java objets Collection et Collections bien connus.


API: Collections est un ensemble de méthodes statiques utilitaires. Les classes représentant les objets API sont souvent définies comme suit: final, car cela garantit (au moment de la compilation) qu'aucun client ne peut jamais "mettre en œuvre" cet objet et qu'elles peuvent dépendre de "appelant" ses méthodes statiques, par exemple.

Collections.emptySet();

Puisque tous les clients sont "appelants" mais pas "implementation", les auteurs de JDK sont libres d'ajouter de nouvelles méthodes dans l'objet Collections dans la future version de JDK. Ils peuvent être sûrs qu’il ne pourra casser aucun client, même s’il ya probablement des millions d’usages.


SPI: Collection est une interface qui implique que n'importe qui peut en implémenter sa propre version. Ainsi, les auteurs de JDK ne peuvent pas y ajouter de nouvelles méthodes car cela briserait tous les clients ayant écrit leur propre implémentation Collection (*). .

En règle générale, si une méthode supplémentaire doit être ajoutée, nouvelle interface, par ex. Collection2 qui étend l'ancien doit être créé. Le client SPI peut alors décider de migrer vers la nouvelle version de SPI et de mettre en œuvre sa méthode supplémentaire ou de conserver l'ancienne version.


Vous avez peut-être déjà vu le point. Si vous combinez les deux éléments dans une seule classe, votre API est bloquée de tout ajout. C'est aussi la raison pour laquelle les bonnes Java API et les frameworks n'exposent pas abstract class car ils bloqueraient leur évolution future en ce qui concerne la compatibilité ascendante.

Si quelque chose n'est toujours pas clair, je vous recommande de vérifier cette page , ce qui explique ce qui précède plus en détail.


(*) Notez que ceci n’est vrai que jusqu’à Java 1.8 qui introduit le concept de méthodes default définies dans une interface.

4
Martin Janíček

Dans le monde Java, différentes technologies se veulent modulaires et "connectables" à un serveur d'applications. Il y a alors une différence entre

  • le serveur d'application
    • [SPI]
  • la technologie enfichable
    • [API]
  • l'application de l'utilisateur final

JTA (le gestionnaire de transactions) et JCA (adaptateur pour JMS ou base de données) en sont deux exemples. Mais il y en a d'autres.

L'implémenteur d'une telle technologie enfichable doit alors implémenter le SPI pour être enfichable dans l'application. serveur et fournit une API à utiliser par l’application de l’utilisateur final. Un exemple de JCA est l’interface ManagedConnection qui fait partie du SPI et la Connexion qui fait partie de l’API de l’utilisateur final.

2
ewernli