aracılığıyla genel hizmet uygulamalarını yükleme java.util.ServiceLoader
'u kullanarak bazı aksaklıklar yaşadım ve bazı sorular bana oluştu. Ben açıkça belirli cins sadece uygulamaları yüklemek için ServiceLoader
anlayamadıjava.util.ServiceLoader
public interface Service<T> { ... }
:
Ben genel bir hizmet olduğunu varsayalım.
ServiceLoader<Service<String>> services =
ServiceLoader.load(Service.class); // Fail.
Sorum şu: güvenle jenerik hizmet uygulamalarını yüklemek için ServiceLoader
kullanmak mantıklı yolları nelerdir?
Yukarıdaki soruyu sorduktan ve Paŭlo'nun cevabından önce bir çözüm bulmayı başardım.
public interface Service<T> { ...
// true if an implementation can handle the given `t' type; false otherwise.
public boolean canHandle(Class<?> t) { ...
public final class StringService implements Service<String> { ...
@Override public boolean canHandle(Class<?> t) {
if (String.class.isAssignableFrom(type))
return true;
return false;
}
public final class DoubleService implements Service<Double> { ...
// ...
public final class Services { ...
public static <T> Service<T> getService(Class<?> t) {
for (Service<T> s : ServiceLoader.load(Service.class))
if (s.canServe(t))
return s;
throw new UnsupportedOperationException("No servings today my son!");
}
(Başlangıçta benim arabirimde bir yöntemi boolean canHandle(T t)
vardı kendim için ikincisi kullanıyorum.) boolean canServe(Object o)
için boolean canServe(Class<?> t)
değiştirilmesi ve aynı zamanda aynı şekilde <T> Service<T> getService(Class<?> t)
değişen daha dinamik olabilir
Teşekkürler! Çözümünüz * sunduğum ayrıntıları göz önünde bulundurarak çalışabilir. Ancak henüz test etmedim, çünkü üzerinde çalıştığım proje için bir * zarif * çözüm buldum. Sorumu sunmak için sorumu düzenledim. Ayrıca, bir yan notta: Böyle bir şey uygulamak çok mu karmaşık olurdu? 'META-INF/services/com.example.Servis' 'com.example.Hizmet 'dosyası şu gibi bir şey içerir: ' = com.example.impl.StringService = com.example.impl.DoubleService' veya daha ayrıntılı bir şey. –
Çok karmaşık değil, ancak bunu kendiniz yapmanız gerekiyor. ('ServiceLoader'ın kullandığı dosyalar ile çelişmemek için başka bir dizin kullanın.) Bir keresinde' ServiceLoader 'mekanizmasını 1,5 için kendim yeniden tasarladım, daha sonra programımın diğer bölümlerinin zaten 1,6'ya ihtiyaç duyduğunu buldum. ve onu attı. –