ממשק ספקי Java

1. סקירה כללית

Java 6 הציגה תכונה לגילוי וטעינה של יישומים התואמים לממשק נתון: ממשק ספקי שירות (SPI).

במדריך זה נציג את רכיבי Java SPI ונראה כיצד אנו יכולים להחיל אותו על מקרה שימוש מעשי.

2. מונחים והגדרות של Java SPI

Java SPI מגדיר ארבעה מרכיבים עיקריים

2.1. שֵׁרוּת

קבוצה ידועה של ממשקי תכנות ושיעורים המספקים גישה לפונקציונליות מסוימת או לתכונה מסוימת.

2.2. ממשק ספקי שירות

ממשק או מחלקה מופשטת הפועלת כ- proxy או כנקודת סיום לשירות.

אם השירות הוא ממשק אחד, זהה לממשק נותני שירותים.

שירות ו- SPI יחד ידועים במערכת האקולוגית של Java כ- API.

2.3. ספק שירות

יישום ספציפי של ה- SPI. ספק השירות מכיל מחלקה קונקרטית אחת או יותר המיישמות או מרחיבות את סוג השירות.

ספק שירות מוגדר ומזוהה באמצעות קובץ תצורה של ספק אותו אנו מכניסים לספריית המשאבים META-INF / שירותים. שם הקובץ הוא השם המלא של SPI ותוכנו הוא השם המלא של יישום ה- SPI.

ספק השירות מותקן בצורה של הרחבות, קובץ צנצנת אותו אנו מציבים בנתיב הכיתה של היישום, בנתיב הכיתה של סיומת Java או בשביל הכיתה שהוגדר על ידי המשתמש.

2.4. ServiceLoader

בלב ה- SPI הוא ה- ServiceLoader מעמד. לתפקיד זה לגלות ולהעמיס יישומים בעצלתיים. היא משתמשת בכביש ההקשר לאיתור יישומי ספקים והכנסתם למטמון פנימי.

3. דוגמאות SPI במערכת האקולוגית של Java

Java מספקת SPI רבים. להלן מספר דוגמאות של ממשק נותני השירות והשירות שהוא מספק:

  • מטבע שםספק: מספק סמלי מטבע מקומיים עבור מַטְבֵּעַ מעמד.
  • ספק שם: מספק שמות מקומיים עבור אזור מעמד.
  • ספק זמן: מספק שמות אזורי זמן מקומיים עבור ה- אזור זמן מעמד.
  • תאריך פורמט ספק: מספק פורמטים של תאריך ושעה עבור אזור מוגדר.
  • NumberFormat ספק: מספק ערכים כספיים, שלמים ואחוזים עבור ה- מספר פורמט מעמד.
  • נהג: החל מגרסה 4.0, ה- API של JDBC תומך בתבנית SPI. גרסאות ישנות יותר משתמשות ב- Class.forName () שיטה לטעינת נהגים.
  • התמדה ספק: מספק יישום ה- API של JPA.
  • ספק Json: מספק אובייקטים לעיבוד JSON.
  • ספק: מספק אובייקטים מחייבים של JSON.
  • סיומת: מספק הרחבות עבור מיכל CDI.
  • ConfigSourceProvider: מספק מקור לאחזור מאפייני תצורה.

4. חלון ראווה: יישום שערי מטבע

כעת, לאחר שהבנו את היסודות, נתאר את הצעדים הנדרשים להגדרת יישום שער חליפין.

כדי להדגיש את השלבים האלה, עלינו להשתמש לפחות בשלושה פרויקטים: שער חליפין-API, שערי חליפין ו יישום שער החליפין.

בפרק משנה 4.1. נסקור את שֵׁרוּת, ה SPI וה ServiceLoaderדרך המודול שערי חליפין-API, ואז בסעיף משנה 4.2. אנו מיישמים את שלנו שֵׁרוּת ספק ב שער החליפין ולבסוף, נקבץ הכל בסעיף משנה 4.3 דרך המודול יישום שער החליפין.

למעשה, אנו יכולים לספק כמה מודולים שאנחנו צריכים עבור ה- service ספק ולהפוך אותם לזמינים במסלול הכיתה של המודול יישום שער החליפין.

4.1. בניית ה- API שלנו

אנו מתחילים ביצירת פרויקט Maven בשם שער חליפין-API. זה נוהג טוב שהשם מסתיים במונח apiאבל אנחנו יכולים לקרוא לזה איך שלא יהיה.

לאחר מכן אנו יוצרים מחלקת מודלים לייצוג מטבעות שער:

חבילה com.baeldung.rate.api; הצעת מחיר בכיתה ציבורית {מטבע מחרוזת פרטי; תאריך LocalDate פרטי; ...}

ואז אנו מגדירים את שלנו שֵׁרוּת לאחזור הצעות מחיר על ידי יצירת הממשק ציטוט מנהל:

חבילה com.baeldung.rate.api ממשק ציבורי QuoteManager {רשימה getQuotes (מחרוזת בסיס מטבע, תאריך LocalDate); }

לאחר מכן, אנו יוצרים SPI לשירותנו:

חבילה com.baeldung.rate.spi; ממשק ציבורי ExchangeRateProvider {QuoteManager create (); }

ולבסוף, עלינו ליצור מחלקת שירות ExchangeRate.java שיכול לשמש את קוד הלקוח. כיתה זו נציגה ל ServiceLoader.

ראשית, אנו קוראים לשיטת המפעל הסטטית לִטעוֹן() לקבל מופע של ServiceLoader:

Loader ServiceLoader = ServiceLoader .load (ExchangeRateProvider.class); 

ואז אנו קוראים ל לְחַזֵר() שיטה לחיפוש ואחזור כל היישומים הזמינים.

Iterator = loader.iterator (); 

תוצאת החיפוש נשמרת במטמון כדי שנוכל להפעיל את ServiceLoader.reload () שיטה על מנת לגלות יישומים חדשים שהותקנו:

Iterator = loader.reload (); 

והנה מחלקת השירות שלנו:

מחלקה ציבורית ExchangeRate {ServiceLoader loader = ServiceLoader .load (ExchangeRateProvider.class); ספקי איטרטורים ציבוריים (רענון בוליאני) {if (רענון) {loader.reload (); } החזר loader.iterator (); }}

כעת, כשיש לנו שירות לקבלת כל היישומים המותקנים, אנו יכולים להשתמש בכולם בקוד הלקוח שלנו כדי להרחיב את היישום שלנו או רק אחד על ידי בחירת יישום מועדף.

שים לב כי מחלקת כלי עזר זו אינה נדרשת להיות חלק מה- api פּרוֹיֶקט. קוד לקוח יכול לבחור להפעיל ServiceLoader שיטות עצמה.

4.2. בניית נותן השירות

בואו ניצור כעת פרויקט Maven בשם שער חליפין ואנחנו מוסיפים את התלות ב- API ל- pom.xml:

 שער חליפין com.baeldung-api 1.0.0-SNAPSHOT 

ואז אנו יוצרים מחלקה המיישמת את ה- SPI שלנו:

מחלקה ציבורית YahooFinanceExchangeRateProvider מיישמת את ExchangeRateProvider {@Override ציבורי ציבורי מנהל ליצור () {להחזיר YahooQuoteManagerImpl חדש (); }}

וכאן היישום של QuoteManager מִמְשָׁק:

מחלקה ציבורית YahooQuoteManagerImpl מיישם את QuoteManager {@Override Public List getQuotes (String baseCurrency, LocalDate date) {// אחזור מ- Yahoo API}}

על מנת להתגלות, אנו יוצרים קובץ תצורה של ספק:

META-INF / services / com.baeldung.rate.spi.ExchangeRateProvider 

תוכן הקובץ הוא שם הכיתה המלא של יישום ה- SPI:

com.baeldung.rate.impl.YahooFinanceExchangeRateProvider 

4.3. לשים את זה ביחד

לבסוף, בואו ניצור פרויקט לקוח שנקרא יישום שער החליפין והוסף את שער החליפין-תלות api למסלול הכיתה:

 שער חליפין com.baeldung-api 1.0.0-SNAPSHOT 

בשלב זה אנו יכולים להתקשר ל- SPI מהיישום שלנו:

ExchangeRate.providers (). ForEach (ספק -> ...);

4.4. הפעלת האפליקציה

בואו נתמקד בבניית כל המודולים שלנו:

חבילה נקייה mvn 

ואז אנו מריצים את היישום שלנו עם ג'אווה פקודה מבלי לקחת בחשבון את הספק:

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

עכשיו נכלול את הספק שלנו ב- java.ext.dirs הרחבה ואנחנו מריצים את היישום שוב:

java -Djava.ext.dirs = $ JAVA_HOME / jre / lib / ext: ./ exchange-impl-impl / target: ./ exchange-impl-impl / target / תלוי -cp ./exchange-rate-api/target/ exchange-rate-api-1.0.0-SNAPSHOT.jar: ./ exchange exchange-app / target / exchange-rate-app-1.0.0-SNAPSHOT.jar com.baeldung.rate.app.MainApp 

אנו יכולים לראות שהספק שלנו טעון.

5. מסקנה

כעת, לאחר שבדקנו את מנגנון ה- Java SPI באמצעות שלבים מוגדרים היטב, יהיה ברור לראות כיצד להשתמש ב- Java SPI ליצירת מודולים הניתנים להרחבה או להחלפה.

למרות שהדוגמה שלנו השתמשה בשירות שער החליפין של יאהו כדי להראות את כוח החיבור לממשקי API חיצוניים קיימים אחרים, מערכות הייצור אינן צריכות להסתמך על ממשקי API של צד שלישי כדי ליצור יישומי SPI נהדרים.

את הקוד, כרגיל, ניתן למצוא ב- Github.