Tergantung pada persyaratan khusus Anda, dalam beberapa kasus mekanisme loader layanan Java mungkin mencapai apa yang Anda cari.
Singkatnya, ini memungkinkan pengembang untuk secara eksplisit menyatakan bahwa suatu kelas mensubklasifikasikan beberapa kelas lain (atau mengimplementasikan beberapa antarmuka) dengan mendaftarkannya dalam file di direktori file JAR / WAR META-INF/services. Kemudian dapat ditemukan menggunakan java.util.ServiceLoaderkelas yang, ketika diberi Classobjek, akan menghasilkan instance dari semua subclass yang dideklarasikan dari kelas itu (atau, jika Classmewakili antarmuka, semua kelas yang mengimplementasikan antarmuka itu).
Keuntungan utama dari pendekatan ini adalah bahwa tidak perlu secara manual memindai seluruh classpath untuk subclass - semua logika penemuan terkandung dalam ServiceLoaderkelas, dan itu hanya memuat kelas yang secara eksplisit dinyatakan dalam META-INF/servicesdirektori (tidak setiap kelas di classpath) .
Namun, ada beberapa kelemahan:
- Itu tidak akan menemukan semua subclass, hanya yang subclass dinyatakan secara eksplisit. Dengan demikian, jika Anda harus benar-benar menemukan semua subclass, pendekatan ini mungkin tidak cukup.
- Ini mengharuskan pengembang untuk secara eksplisit mendeklarasikan kelas di bawah
META-INF/servicesdirektori. Ini merupakan beban tambahan bagi pengembang, dan bisa rawan kesalahan.
- The
ServiceLoader.iterator()menghasilkan contoh subclass, bukan mereka Classobjek. Ini menyebabkan dua masalah:
- Anda tidak bisa mengatakan bagaimana subkelas dikonstruksi - konstruktor no-arg digunakan untuk membuat instance.
- Dengan demikian, subclass harus memiliki konstruktor default, atau harus eksplisit menyatakan konstruktor no-arg.
Rupanya Java 9 akan mengatasi beberapa kekurangan ini (khususnya, yang berkaitan dengan instantiasi subkelas).
Sebuah contoh
Misalkan Anda tertarik menemukan kelas yang mengimplementasikan antarmuka com.example.Example:
package com.example;
public interface Example {
public String getStr();
}
Kelas com.example.ExampleImplmengimplementasikan antarmuka itu:
package com.example;
public class ExampleImpl implements Example {
public String getStr() {
return "ExampleImpl's string.";
}
}
Anda akan mendeklarasikan kelas ExampleImpladalah implementasi Exampledengan membuat file yang META-INF/services/com.example.Exampleberisi teks com.example.ExampleImpl.
Kemudian, Anda dapat memperoleh instance dari setiap implementasi Example(termasuk instance dari ExampleImpl) sebagai berikut:
ServiceLoader<Example> loader = ServiceLoader.load(Example.class)
for (Example example : loader) {
System.out.println(example.getStr());
}
// Prints "ExampleImpl's string.", plus whatever is returned
// by other declared implementations of com.example.Example.