SPI (Antara Muka Pembekal Perkhidmatan) ialah mekanisme penemuan perkhidmatan yang terbina dalam JDK, yang boleh digunakan untuk mendayakan sambungan rangka kerja dan komponen penggantian Untuk pembangunan dalam rangka kerja, seperti Dubbo, Spring, Common-Logging, JDBC, dsb., gunakan mekanisme SPI dan gunakan pelaksanaan yang berbeza untuk antara muka yang sama untuk memberikannya kepada pengguna yang berbeza, dengan itu meningkatkan kebolehskalaan rangka kerja.
SPI terbina dalam Java menghuraikan classPath dan fail yang dinamakan dengan nama antara muka yang layak sepenuhnya dalam direktori META-INF/services/ pakej jar melalui kelas java.util.ServiceLoader Dan muatkan kelas pelaksanaan antara muka yang dinyatakan dalam fail untuk menyelesaikan panggilan.
public interface VedioSPI { void call(); }
public class Mp3Vedio implements VedioSPI { @Override public void call() { System.out.println("this is mp3 call"); } }
public class Mp4Vedio implements VedioSPI { @Override public void call() { System.out.println("this is mp4 call"); } }
Dalam direktori sumber projek Cipta fail com.skywares.fw.juc.spi.VedioSPI dalam direktori META-INF/services/ baharu.
public class VedioSPITest { public static void main(String[] args) { ServiceLoader<VedioSPI> serviceLoader =ServiceLoader.load(VedioSPI.class); serviceLoader.forEach(t->{ t.call(); }); } }
Penerangan: Java melaksanakan spi melalui ServiceLoader untuk mencari kelas alat yang disediakan oleh perkhidmatan.
Di atas hanyalah contoh mudah untuk melaksanakan fungsi SPI terbina dalam Java. Prinsip pelaksanaan ialah ServiceLoader ialah kelas alat Java terbina dalam untuk mencari antara muka perkhidmatan yang menyediakan antara muka dengan memanggil kaedah load() dan akhirnya merentasi untuk mengakses kelas pelaksanaan perkhidmatan yang menyediakan antara muka satu demi satu. .
Anda boleh mencari daripada kod sumber:
Kelas ServiceLoader sendiri melaksanakan antara muka Iterable dan melaksanakan kaedah iterator di dalamnya . Kaedah iterator Kaedah dalam kelas dalaman LazyIterator dipanggil dalam pelaksanaan Selepas menghuraikan fail antara muka pembekal perkhidmatan, keputusan akhir diletakkan dalam Iterator dan kembali ke kelas pelaksanaan antara muka pembekal perkhidmatan.
Fail yang sepadan bagi semua antara muka pembekal perkhidmatan diletakkan dalam direktori META-INF/services/ Jenis akhir menentukan bahawa direktori PREFIX tidak boleh ditukar.
Walaupun idea mekanisme SPI yang disediakan oleh java sangat bagus, ia juga mempunyai kelemahan yang sepadan. Butirannya adalah seperti berikut:
Kaedah terbina dalam Java hanya boleh diperoleh melalui traversal
Antara muka pembekal perkhidmatan mesti diletakkan dalam META -INF/perkhidmatan/ direktori.
Mensasarkan masalah yang wujud dalam spi java, mekanisme SPI Spring mengikut idea SPI, tetapi mengembangkan dan mengoptimumkannya.
Spring SPI mengikut idea reka bentuk Java SPI menggunakan kaedah spring.factories untuk melaksanakan mekanisme SPI, yang boleh menyediakan rangka kerja Spring tanpa mengubah suai sumber Spring. kod.
Contoh musim bunga
Antara muka definisi
public interface DataBaseSPI { void getConnection(); }
Pelaksanaan berkaitan
#DB2实现 public class DB2DataBase implements DataBaseSPI { @Override public void getConnection() { System.out.println("this database is db2"); } } #Mysql实现 public class MysqlDataBase implements DataBaseSPI { @Override public void getConnection() { System.out.println("this is mysql database"); } }
1 Dalam direktori META-INF projek, tambahkan fail spring.factories
2 Isikan maklumat antara muka yang berkaitan, kandungannya adalah seperti berikut
com.skywares.fw.juc.springspi.DataBaseSPI = com.skywares.fw .juc.springspi.DB2DataBase, com.skywares.fw.juc.springspi.MysqlDataBase
Penerangan Berbilang pelaksanaan dipisahkan dengan koma.
Kelas ujian yang berkaitan
public class SpringSPITest { public static void main(String[] args) { List<DataBaseSPI> dataBaseSPIs =SpringFactoriesLoader.loadFactories(DataBaseSPI.class, Thread.currentThread().getContextClassLoader()); for(DataBaseSPI datBaseSPI:dataBaseSPIs){ datBaseSPI.getConnection(); } } }
Hasil keluaran
Daripada contoh kita dapat melihat bahawa Spring menggunakan spring.factories untuk melaksanakan SPI dan java pelaksanaan SPI adalah sangat serupa, tetapi pengoptimuman yang relevan bagi kaedah spi spring untuk spi java adalah seperti berikut:
Java SPI ialah perkhidmatan menyediakan antara muka yang sepadan dengan fail konfigurasi dan fail konfigurasi menyimpan semasa Semua kelas pelaksanaan antara muka, berbilang antara muka pembekal perkhidmatan sepadan dengan berbilang fail konfigurasi, semua konfigurasi berada dalam direktori perkhidmatan; yang menyimpan berbilang Antara muka dan kelas pelaksanaan yang sepadan dikonfigurasikan dengan nama antara muka yang layak sepenuhnya sebagai kunci dan kelas pelaksanaan sebagai nilai Berbilang kelas pelaksanaan dipisahkan dengan koma. Terdapat hanya satu fail konfigurasi, spring.factories.
Jadi bagaimanakah spring melaksanakan SpI dengan memuatkan spring.factories Kita boleh menganalisisnya lagi melalui kod sumber?
Penerangan: Dapatkan laluan fail META-INF/spring.factories dalam semua pakej balang dan kembalikannya sebagai nilai penghitungan. Lintas laluan fail spring.factories, muatkan dan huraikan satu demi satu, sepadukan nama kelas pelaksanaan jenis factoryClass, dapatkan nama kelas penuh kelas pelaksanaan dan lakukan operasi contoh kelas Kod sumber yang berkaitan adalah seperti berikut:
Penjelasan: Instantiation melaksanakan permulaan yang sepadan melalui refleksi.
Atas ialah kandungan terperinci Bagaimana untuk melaksanakan mekanisme SPI SpringBoot. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!