На днях я наткнулся на некоторые неудобства, используя java.util.ServiceLoader
и некоторые вопросы сформировался во мне.
Предположим, у меня есть общий сервис:
public interface Service<T> { ... }
Я не мог явно указать ServiceLoader
загружать только реализации с определенным универсальным типом.
ServiceLoader<Service<String>> services =
ServiceLoader.load(Service.class); // Fail.
Мой вопрос: каковы разумные способы использования ServiceLoader
для безопасной загрузки реализаций универсального сервиса?
Задав вышеупомянутый вопрос и до ответа Паоло, мне удалось придумать решение.
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!");
}
Изменение логического canServe (Class > T)
на логическое canServe (Object o)
, а также изменение
таким же образом может быть более динамичным (я использую последний для себя, поскольку вначале у меня был метод boolean canHandle (T t)
в моем интерфейсе.)