Apa perbedaan antara Antarmuka Penyedia Layanan (SPI) dan Antarmuka Pemrograman Aplikasi (API) ?
Lebih khusus, untuk perpustakaan Java, apa yang membuatnya menjadi API dan / atau SPI?
Apa perbedaan antara Antarmuka Penyedia Layanan (SPI) dan Antarmuka Pemrograman Aplikasi (API) ?
Lebih khusus, untuk perpustakaan Java, apa yang membuatnya menjadi API dan / atau SPI?
Jawaban:
Dengan kata lain, API memberi tahu Anda apa yang dilakukan kelas / metode tertentu untuk Anda, dan SPI memberi tahu Anda apa yang harus Anda lakukan untuk menyesuaikan diri.
Biasanya API dan SPI terpisah. Misalnya, dalam JDBC yang Driver
kelas merupakan bagian dari SPI: Jika Anda hanya ingin menggunakan JDBC, Anda tidak perlu menggunakannya secara langsung, tapi semua orang yang menerapkan driver JDBC harus menerapkan kelas itu.
Namun, terkadang mereka tumpang tindih. The Connection
antarmuka adalah baik SPI dan API: Anda menggunakannya secara rutin ketika Anda menggunakan driver JDBC dan perlu dilaksanakan oleh pengembang driver JDBC.
@SomeAnnotation
ke kelas saya untuk mengambilnya dengan beberapa kerangka kerja, akankah kelas anotasi ini SomeAnnotation.class
dianggap sebagai bagian dari SPI, meskipun saya tidak secara teknis memperluas atau mengimplementasikannya?
Dari Java Efektif, Edisi ke-2 :
Kerangka kerja penyedia layanan adalah suatu sistem di mana banyak penyedia layanan mengimplementasikan suatu layanan, dan sistem membuat implementasi tersedia untuk kliennya, memisahkan mereka dari implementasi.
Ada tiga komponen penting dari kerangka penyedia layanan: antarmuka layanan, yang diimplementasikan oleh penyedia; API pendaftaran penyedia, yang digunakan sistem untuk mendaftarkan implementasi, memberi klien akses ke sana; dan API akses layanan, yang digunakan klien untuk mendapatkan mesin virtual layanan. API akses layanan biasanya memungkinkan tetapi tidak mengharuskan klien untuk menentukan beberapa kriteria untuk memilih penyedia. Dengan tidak adanya spesifikasi seperti itu, API mengembalikan contoh implementasi default. API akses layanan adalah "pabrik statis fleksibel" yang membentuk dasar kerangka penyedia layanan.
Komponen keempat opsional dari kerangka penyedia layanan adalah antarmuka penyedia layanan, yang diterapkan penyedia untuk membuat instance implementasi layanan mereka. Dengan tidak adanya antarmuka penyedia layanan, implementasi didaftarkan oleh nama kelas dan instantiated reflektif (Butir 53). Dalam kasus JDBC, Connection memainkan bagian dari antarmuka layanan, DriverManager.registerDriver adalah API pendaftaran penyedia, DriverManager.getConnection adalah API akses layanan, dan Driver adalah antarmuka penyedia layanan.
Ada banyak varian pola kerangka penyedia layanan. Sebagai contoh, API akses layanan dapat mengembalikan antarmuka layanan yang lebih kaya daripada yang dibutuhkan oleh penyedia, menggunakan pola Adaptor [Gamma95, hal. 139]. Berikut ini adalah implementasi sederhana dengan antarmuka penyedia layanan dan penyedia default:
// 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();
}
}
Perbedaan antara API dan SPI muncul ketika API juga menyediakan beberapa implementasi konkret. Dalam hal ini, penyedia layanan harus mengimplementasikan beberapa API (disebut SPI)
Contohnya adalah JNDI:
JNDI menyediakan antarmuka & beberapa kelas untuk pencarian konteks. Cara default untuk mencari konteks disediakan di IntialContext. Kelas ini secara internal akan menggunakan antarmuka SPI (menggunakan NamingManager) untuk implementasi khusus penyedia.
Lihat Arsitektur JNDI di bawah ini untuk pemahaman yang lebih baik.
API adalah singkatan dari Application Programming Interface, di mana API adalah sarana untuk mengakses layanan / fungsi yang disediakan oleh beberapa jenis perangkat lunak atau platform.
SPI adalah singkatan dari Service Provider Interface, di mana SPI adalah cara untuk menyuntikkan, memperluas atau mengubah perilaku untuk perangkat lunak atau platform.
API biasanya menargetkan klien untuk mengakses layanan dan memiliki properti berikut:
-> API adalah cara terprogram mengakses layanan untuk mencapai perilaku atau keluaran tertentu
-> Dari sudut pandang evolusi API, penambahan tidak ada masalah sama sekali untuk klien
-> Tetapi API yang pernah digunakan oleh klien tidak dapat (dan seharusnya tidak) diubah / dihapus kecuali ada komunikasi yang sesuai, karena merupakan degradasi lengkap dari harapan klien
SPI pada bagian lain ditargetkan untuk penyedia dan memiliki sifat-sifat berikut:
-> SPI adalah cara untuk memperluas / mengubah perilaku perangkat lunak atau platform (dapat diprogram vs. terprogram)
-> Evolusi SPI berbeda dari evolusi API, dalam penghapusan SPI tidak ada masalah
-> Penambahan antarmuka SPI akan menyebabkan masalah dan dapat merusak implementasi yang ada
Untuk penjelasan lebih lanjut klik di sini: Antarmuka Penyedia Layanan
FAQ NetBeans: Apa itu SPI? Apa bedanya dengan API?
API adalah istilah umum - akronim untuk Antarmuka Pemrograman Aplikasi - artinya sesuatu (di Jawa, biasanya beberapa kelas Java) yang dipaparkan oleh perangkat lunak, yang memungkinkan perangkat lunak lain berkomunikasi dengannya.
SPI adalah singkatan dari Service Provider Interface. Ini adalah himpunan bagian dari semua hal yang bisa menjadi API khusus untuk situasi di mana perpustakaan menyediakan kelas yang dipanggil oleh aplikasi (atau perpustakaan API), dan yang biasanya mengubah hal-hal yang dapat dilakukan aplikasi.
Contoh klasik adalah JavaMail. API-nya memiliki dua sisi:
- Sisi API - yang Anda panggil jika Anda sedang menulis klien email atau ingin membaca kotak surat
- Sisi SPI jika Anda menyediakan penangan protokol kawat untuk memungkinkan JavaMail berbicara dengan server jenis baru, seperti berita atau server IMAP
Pengguna API jarang perlu melihat atau berbicara dengan kelas SPI, dan sebaliknya.
Di NetBeans, ketika Anda melihat istilah SPI, biasanya berbicara tentang kelas yang dapat disuntikkan modul saat runtime yang memungkinkan NetBeans untuk melakukan hal-hal baru. Misalnya, ada SPI umum untuk menerapkan sistem kontrol versi. Modul yang berbeda menyediakan implementasi SPI untuk CVS, Subversion, Mercurial, dan sistem kontrol revisi lainnya. Namun, kode yang berhubungan dengan file (sisi API) tidak perlu peduli jika ada sistem kontrol versi, atau apa itu.
Ada satu aspek yang tampaknya tidak terlalu disorot tetapi sangat penting untuk memahami alasan di balik keberadaan perpecahan API / SPI.
Perpecahan API / SPI hanya diperlukan saat platform diharapkan untuk berkembang. Jika Anda menulis API dan "tahu" itu tidak akan memerlukan perbaikan di masa mendatang, tidak ada alasan nyata untuk memecah kode Anda menjadi dua bagian (selain membuat desain objek bersih).
Tapi ini hampir tidak pernah terjadi dan orang perlu memiliki kebebasan untuk mengembangkan API bersama dengan persyaratan di masa depan - dengan cara yang kompatibel.
Perhatikan bahwa semua hal di atas mengasumsikan Anda sedang membangun platform yang digunakan dan / atau diperluas orang lain dan bukan API Anda sendiri di mana Anda memiliki semua kode klien di bawah kendali dan dengan demikian dapat memperbaiki sesuai kebutuhan Anda.
Mari kita tunjukkan pada salah satu objek Java yang terkenal Collection
dan Collections
.
API: Collections
adalah seperangkat metode statis utilitas. Seringkali kelas yang mewakili objek API didefinisikan sebagai final
memastikan (pada waktu kompilasi) bahwa tidak ada klien yang dapat "mengimplementasikan" objek itu dan mereka dapat bergantung pada "memanggil" metode statisnya, misalnya
Collections.emptySet();
Karena semua klien "menelepon" tetapi tidak "menerapkan" , penulis JDK bebas untuk menambahkan metode baru ke Collections
objek di versi JDK yang akan datang. Mereka dapat yakin itu tidak dapat menghancurkan klien mana pun, bahkan jika mungkin ada jutaan penggunaan.
SPI: Collection
adalah antarmuka yang menyiratkan bahwa siapa pun dapat mengimplementasikan versinya sendiri. Dengan demikian, penulis JDK tidak dapat menambahkan metode baru ke dalamnya karena akan menghancurkan semua klien yang menulis sendiriCollection
implementasi (*).
Biasanya ketika metode tambahan diperlukan untuk ditambahkan, antarmuka baru, misalnya Collection2
yang meluas yang sebelumnya perlu dibuat. Klien SPI kemudian dapat memutuskan apakah akan bermigrasi ke versi baru SPI dan mengimplementasikan metode tambahan itu atau apakah akan tetap menggunakan yang lebih lama.
Anda mungkin sudah mengerti intinya. Jika Anda menggabungkan kedua bagian menjadi satu kelas, API Anda diblokir dari penambahan apa pun. Itu juga alasan mengapa API dan Kerangka Java yang bagus tidak terbukaabstract class
karena mereka akan memblokir evolusi masa depan mereka sehubungan dengan kompatibilitas ke belakang.
Jika ada sesuatu yang masih belum jelas, saya sarankan untuk memeriksa halaman ini yang menjelaskan hal di atas secara lebih rinci.
(*) Catatan ini benar hanya sampai Java 1.8 yang memperkenalkan konsep default
metode yang didefinisikan dalam antarmuka.
Saya kira slot SPI ke dalam sistem yang lebih besar dengan mengimplementasikan fitur-fitur tertentu dari API, dan kemudian mendaftarkan dirinya sebagai tersedia melalui mekanisme pencarian layanan. API digunakan oleh kode aplikasi pengguna akhir secara langsung, tetapi dapat mengintegrasikan komponen SPI. Perbedaan antara enkapsulasi dan penggunaan langsung.
Antarmuka penyedia layanan adalah antarmuka layanan yang harus diterapkan oleh semua penyedia. Jika tidak ada implementasi penyedia yang ada bekerja untuk Anda, Anda perlu menulis penyedia layanan Anda sendiri (mengimplementasikan antarmuka layanan) dan mendaftar di suatu tempat (lihat posting berguna oleh Roman).
Jika Anda menggunakan kembali implementasi penyedia antarmuka layanan yang ada, pada dasarnya Anda menggunakan API penyedia tertentu itu, yang mencakup semua metode antarmuka layanan plus beberapa metode publik sendiri. Jika Anda menggunakan metode API penyedia di luar SPI, Anda menggunakan fitur khusus penyedia.
Di dunia Java, berbagai teknologi dimaksudkan untuk menjadi modular dan "pluggable" ke dalam server aplikasi. Kemudian ada perbedaan di antara keduanya
Dua contoh teknologi tersebut adalah JTA (manajer transaksi) dan JCA (adaptor untuk JMS atau database). Tapi ada yang lain.
Pelaksana teknologi pluggable tersebut kemudian harus mengimplementasikan SPI agar dapat dicolokkan ke dalam aplikasi. server dan menyediakan API untuk digunakan oleh aplikasi pengguna akhir. Contoh dari JCA adalah antarmuka ManagedConnection yang merupakan bagian dari SPI, dan Koneksi yang merupakan bagian dari API pengguna akhir.