Rozhranie poskytovateľa služieb Java
1. Prehľad
Java 6 predstavila funkciu na objavovanie a načítanie implementácií zodpovedajúcich danému rozhraniu: Service Provider Interface (SPI).
V tomto tutoriále si predstavíme komponenty Java SPI a ukážeme si, ako ich môžeme aplikovať na prípad praktického použitia.
2. Pojmy a definície Java SPI
Java SPI definuje štyri hlavné komponenty
2.1. Služby
Známa sada programovacích rozhraní a tried, ktoré poskytujú prístup k niektorým špecifickým funkciám alebo vlastnostiam aplikácie.
2.2. Rozhranie poskytovateľa služieb
Rozhranie alebo abstraktná trieda, ktorá slúži ako proxy alebo koncový bod služby.
Ak je službou jedno rozhranie, je to rovnaké ako rozhranie poskytovateľa služby.
Služba a SPI sú v prostredí Java Ecosystem dobre známe ako API.
2.3. Poskytovateľ služieb
Konkrétna implementácia SPI. Poskytovateľ služby obsahuje jednu alebo viac konkrétnych tried, ktoré implementujú alebo rozširujú typ služby.
Poskytovateľ služieb je konfigurovaný a identifikovaný prostredníctvom konfiguračného súboru poskytovateľa, ktorý sme vložili do adresára prostriedkov META-INF / služby. Názov súboru je úplný názov SPI a jeho obsah je úplný názov implementácie SPI.
Poskytovateľ služieb je nainštalovaný vo forme rozšírení, súboru jar, ktorý umiestnime do aplikačnej triedy, do triedy Java alebo do triedy definovanej používateľom.
2.4. ServiceLoader
V srdci SPI je ServiceLoader trieda. To má rolu lenivo objavovať a načítať implementácie. Využíva kontextovú cestu triedy na vyhľadanie implementácií poskytovateľa a na ich vloženie do internej medzipamäte.
3. Vzorky SPI v ekosystéme Java
Java poskytuje veľa SPI. Tu je niekoľko príkladov rozhrania poskytovateľa služieb a služieb, ktoré poskytuje:
- Poskytovateľ meny: poskytuje lokalizované symboly mien pre Mena trieda.
- Poskytovateľ miestneho názvu: poskytuje lokalizované názvy pre Miestne nastavenie trieda.
- Poskytovateľ TimeZoneName: poskytuje lokalizované názvy časových pásiem pre Časové pásmo trieda.
- DateFormatProvider: poskytuje formáty dátumu a času pre zadané miestne nastavenie.
- NumberFormatProvider: poskytuje peňažné, celé a percentuálne hodnoty pre NumberFormat trieda.
- Vodič: od verzie 4.0 podporuje rozhranie JDBC API vzor SPI. Staršie verzie používajú Class.forName () spôsob načítania ovládačov.
- Poskytovateľ Persistence: poskytuje implementáciu API JPA.
- JsonProvider: poskytuje objekty na spracovanie JSON.
- JsonbProvider: poskytuje objekty väzby JSON.
- Prípona: poskytuje rozšírenia pre kontajner CDI.
- ConfigSourceProvider: poskytuje zdroj na načítanie vlastností konfigurácie.
4. Vitrína: Aplikácia výmenných kurzov mien
Teraz, keď chápeme základné informácie, poďme si popísať kroky, ktoré sú potrebné na nastavenie aplikácie výmenného kurzu.
Na zvýraznenie týchto krokov musíme použiť minimálne tri projekty: výmenný kurz-api, výmenný kurz-impl, a výmenný kurz-app.
V pododdiele 4.1. Sa budeme zaoberať Služby, SPI a ServiceLoadercez modul výmenný kurz-api, potom v pododdiele 4.2. implementujeme naše služby poskytovateľ v výmenný kurz-impl modulu a nakoniec všetko spojíme v pododdiele 4.3 prostredníctvom modulu výmenný kurz-app.
V skutočnosti môžeme poskytnúť toľko modulov, koľko potrebujeme pre service poskytovateľ a sprístupniť ich v triede modulu výmenný kurz-app.
4.1. Budovanie nášho API
Začneme vytvorením projektu Maven s názvom výmenný kurz-api. Je dobrým zvykom, že názov sa končí týmto výrazom api, ale môžeme to nazvať akokoľvek.
Potom vytvoríme modelovú triedu na vyjadrenie mien kurzov:
balík com.baeldung.rate.api; public class Quote {private String currency; súkromné LocalDate dátum; ...}
A potom definujeme svoje Služby na načítanie ponúk vytvorením rozhrania QuoteManager:
balíček verejné rozhranie com.baeldung.rate.api QuoteManager {List getQuotes (String baseCurrency, LocalDate date); }
Ďalej vytvoríme SPI pre našu službu:
balíček com.baeldung.rate.spi; verejné rozhranie ExchangeRateProvider {QuoteManager create (); }
A nakoniec musíme vytvoriť triedu nástrojov ExchangeRate.java ktoré môžu byť použité kódom klienta. Táto trieda deleguje na ServiceLoader.
Najskôr vyvoláme statickú továrenskú metódu naložiť() získať inštanciu ServiceLoader:
ServiceLoader loader = ServiceLoader .load (ExchangeRateProvider.class);
A potom vyvoláme iterovať () metóda na vyhľadanie a získanie všetkých dostupných implementácií.
Iterátor = loader.iterator ();
Výsledok vyhľadávania je uložený v pamäti, aby sme mohli vyvolať ServiceLoader.reload () metóda na objavenie novo nainštalovaných implementácií:
Iterátor = loader.reload ();
A tu je naša trieda užitočnosti:
verejná trieda ExchangeRate {ServiceLoader loader = ServiceLoader .load (ExchangeRateProvider.class); verejní poskytovatelia iterátora (boolean refresh) {if (refresh) {loader.reload (); } návrat loader.iterator (); }}
Teraz, keď máme službu na získanie všetkých nainštalovaných implementácií, môžeme ich všetky použiť v klientskom kóde na rozšírenie našej aplikácie alebo iba jednu výberom preferovanej implementácie.
Upozorňujeme, že táto trieda nástrojov nemusí byť súčasťou api projekt. Kód klienta sa môže rozhodnúť vyvolať Samotné metódy ServiceLoader.
4.2. Budovanie poskytovateľa služieb
Poďme teraz vytvoriť projekt Maven s názvom výmenný kurz-impl a do API pridáme závislosť API pom.xml:
com.baeldung exchange-rate-api 1.0.0-SNAPSHOT
Potom vytvoríme triedu, ktorá implementuje náš SPI:
public class YahooFinanceExchangeRateProvider implementuje ExchangeRateProvider {@Override public QuoteManager create () {return new YahooQuoteManagerImpl (); }}
A tu implementácia QuoteManager rozhranie:
verejná trieda YahooQuoteManagerImpl implementuje QuoteManager {@Override verejný zoznam getQuotes (reťazec baseCurrency, dátum LocalDate) {// načítanie z rozhrania Yahoo API}}
Aby sme boli odhalení, vytvoríme konfiguračný súbor poskytovateľa:
META-INF / services / com.baeldung.rate.spi.ExchangeRateProvider
Obsahom súboru je úplný názov triedy implementácie SPI:
com.baeldung.rate.impl.YahooFinanceExchangeRateProvider
4.3. Dať to dokopy
Na záver vytvoríme klientsky projekt s názvom výmenný kurz-app a pridajte závislý výmenný kurz-api do triedy:
com.baeldung exchange-rate-api 1.0.0-SNAPSHOT
V tomto okamihu môžeme zavolať SPI z našej aplikácie:
ExchangeRate.providers (). ForEach (poskytovateľ -> ...);
4.4. Spustenie aplikácie
Poďme sa teraz zamerať na zostavenie všetkých našich modulov:
mvn čistý balíček
Potom spustíme našu aplikáciu s Java príkaz bez zohľadnenia poskytovateľa:
java -cp ./exchange-rate-api/target/exchange-rate-api-1.0.0-SNAPSHOT.jar:./exchange-rate-app/target/exchange-rate-app-1.0.0-SNAPSHOT.jar com.baeldung.rate.app.MainApp
Teraz zahrnieme nášho poskytovateľa do java.ext.dirs rozšírenie a aplikáciu znovu spustíme:
java -Djava.ext.dirs = $ JAVA_HOME / jre / lib / ext: ./ výmenný kurz-impl / cieľ: ./ výmenný kurz-impl / cieľ / záleží -cp ./exchange-rate-api/target/ výmenný kurz-api-1.0.0-SNAPSHOT.jar: ./ výmenný kurz-aplikácia / cieľ / výmenný kurz-aplikácia-1.0.0-SNAPSHOT.jar com.baeldung.rate.app.MainApp
Vidíme, že náš poskytovateľ je načítaný.
5. Záver
Teraz, keď sme preskúmali mechanizmus Java SPI prostredníctvom dobre definovaných krokov, by malo byť jasné, ako používať Java SPI na vytvorenie ľahko rozšíriteľných alebo vymeniteľných modulov.
Aj keď náš príklad použil službu výmenného kurzu Yahoo na preukázanie sily pripojenia k iným existujúcim externým API, produkčné systémy sa pri vytváraní skvelých aplikácií SPI nemusia spoliehať na API tretích strán.
Kód, ako obvykle, nájdete na Githube.