Как определить реализацию "по умолчанию" в 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 определяет как сервис "по умолчанию" (или "лучший") для внедрения в мои зависимые сервисы.

Другие вопросы по тегам