Как определить реализацию "по умолчанию" в HK2?
Я использую HK2 для разрешения зависимостей сервисов в моем веб-сервисе в Джерси / Джетти. У меня есть ситуация, когда для одного конкретного интерфейса я хочу использовать конкретную реализацию в качестве реализации "по умолчанию". Под "по умолчанию" я подразумеваю отсутствие имен или квалификаторов - это то, что вы получите, если не будете указывать какие-либо аннотации в верхней части поля или аргумента. Однако в нескольких очень специфических ситуациях я хочу предоставить альтернативную реализацию, которая будет дополнена аннотацией.
В результате моих экспериментов я действительно получил это работать надежно с помощью ranked()
квалификатор в моих связках. Похоже, самый высокий ранг становится по умолчанию. Однако я не понимаю, почему это работает, и я обеспокоен тем, что пишу код, который зависит от недокументированных деталей реализации HK2, которые могут измениться при обновлении версий.
Вот надуманный пример интересных частей того, что я делаю. Является ranked()
что я должен использовать, чтобы указать "по умолчанию" и аннотированные варианты услуг? Должен ли я использовать другую технику?
public interface IFoo {
public String getString();
}
public class DefaultImpl implements IFoo {
public String getString() {
return "Default Implementation";
}
}
public class AnnotatedImpl implements IFoo {
public String getString() {
return "Annotated Implementation";
}
}
public class Bindings extends AbstractBinder {
@Override
public void configure() {
ServiceBindingBuilder<DefaultImpl> defaultImpl =
bind(DefaultImpl.class)
.to(IFoo.class);
defaultImpl.ranked(9);
ServiceBindingBuilder<AnnotatedImpl> annotatedImpl =
bind(AnnotatedImpl.class)
.qualifiedBy(new MyAnnotationQualifier())
.to(IFoo.class);
annotatedImpl.ranked(1);
}
}
public class MyService {
@Inject
public MyService(
IFoo defaultImplementation,
@MyAnnotation
IFoo annotatedImplementation) {
// ... my code here ...
}
}
1 ответ
Я наткнулся на некоторую документацию на веб-сайте HK2, которая соответствует поведению, которое я наблюдаю.
Если имеется более одного виджета (например, виджет - это интерфейс, который может иметь много реализаций), то лучший виджет будет возвращен из метода getService. Лучший экземпляр сервиса - это сервис с самым высоким рейтингом или самым низким идентификатором сервиса. Рейтинг службы находится в ее дескрипторе и может быть изменен в любое время во время выполнения. Идентификатор службы для службы является системным назначенным значением для дескриптора, когда он связан с ServiceLocator. Назначенное системой значение является монотонно возрастающим значением. Таким образом, если два сервиса имеют одинаковое ранжирование, лучший сервис будет связан с самым старым дескриптором, привязанным к системе.
Поэтому я использую ranked()
на моих привязках правильно. Это один из двух способов управления тем, что HK2 определяет как сервис "по умолчанию" (или "лучший") для внедрения в мои зависимые сервисы.