Vertx + Jersey + HK2: автопривязки ServiceLocator с использованием @Contract и @Service

Я пытаюсь использовать vertx-jersey для создания веб-сервиса, в котором я может внедрить свои собственные пользовательские службы, а также некоторые более стандартные объекты, такие как сам экземпляр vertx.

На данный момент я инициализирую веб-сервер так (т.е. следуя этот пример):

Vertx vertx = Vertx.vertx();
vertx.runOnContext(aVoid -> {

    JsonObject jerseyConfiguration = new JsonObject();
    // ... populate the config with base path, resources, host, port, features, etc.

    vertx.getOrCreateContext().config().put("jersey", jerseyConfiguration);

    ServiceLocator locator = ServiceLocatorUtilities.bind(new HK2JerseyBinder());

    JerseyServer server = locator.getService(JerseyServer.class);
    server.start();
});

Проблема, с которой я столкнулся, заключается в том, что я также хочу иметь возможность использовать внедрение зависимостей, чтобы я мог автоматически подключать другие мои службы, используя аннотации @Contract и @Service HK2.

Проблема в том, что я уже создаю ServiceLocator, используя ServiceLocatorUtilities, в котором я явно привязываю HK2JerseyBinder, и, насколько я понимаю, я должен создавать только один экземпляр ServiceLocator, в котором все должно быть доступно/привязано.

Я также знаю, что вместо этого я мог бы вызвать ServiceLocatorUtilities.createAndPopulateServiceLocator(), однако похоже, что JerseyServer вместе со всем остальным, связанным с HK2JerseyBinder, будет пропущено, поскольку они не аннотированы.

Есть ли способ, которым я могу сделать и то, и другое или как-то обойти это?


person Community    schedule 27.08.2017    source источник
comment
Каждый ServiceLocator имеет DynamicConfigurationService (javaee.github.io/ hk2/apidocs/org/glassfish/hk2/api/). Отсюда вы можете получить Populator (javaee.github. io/hk2/apidocs/org/glassfish/hk2/api/). У заполнителя есть методы, которые можно использовать для динамического добавления сервисов из (например) файлов обитателей, или из сканирования классов, или из любого другого автоматического механизма, который вы хотите использовать для обнаружения сервисов.   -  person jwells131313    schedule 28.08.2017


Ответы (1)


Чтобы расширить комментарий jwell:

ServiceLocatorUtilities соответствует своему названию: это просто утилита, помогающая создать ServiceLocator. Чтобы создать его без утилит, вы должны использовать файл ServiceLocatorFactory. Это то, что утилита делает под капотом, когда вы вызываете одну из ее функций создания.

ServiceLocator locator = ServiceLocatorFactory().getInstance().create(null);

Если вы хотите динамически добавлять услуги в локатор, вы можете использовать DynamicConfigurationService, который предоставляется по умолчанию.

DynamicConfigurationService dcs = locator.getService(DynamicConfigurationService.class);

У этой службы есть Populator, который вы можете получить и вызвать метод populate для заполнения локатора услугами из вашего файлы обитателей (вы можете получить их с помощью генератор).

Populator populator = dcs.getPopulator();
populator.populate();

Это все ServiceLocatorUtilities.createAndPopulateServiceLocator() делает.

public static ServiceLocator createAndPopulateServiceLocator(String name) throws MultiException {
    ServiceLocator retVal = ServiceLocatorFactory.getInstance().create(name);

    DynamicConfigurationService dcs = retVal.getService(DynamicConfigurationService.class);
    Populator populator = dcs.getPopulator();

    try {
        populator.populate();
    }
    catch (IOException e) {
        throw new MultiException(e);
    }

    return retVal;
}

Итак, поскольку у вас уже есть экземпляр локатора, все, что вам нужно сделать, это получить службу динамической конфигурации, получить заполнитель и вызвать его метод populate.

ServiceLocator locator = ServiceLocatorUtilities.bind(new HK2JerseyBinder());
DynamicConfigurationService dcs = locator.getService(DynamicConfigurationService.class);
Populator populator = dcs.getPopulator();
populator.populate();

И если вы хотите сделать это наоборот (сначала население), вы можете сделать

ServiceLocator locator = ServiceLocatorUtilities.createAndPopulateServiceLocator();
ServiceLocatorUtilities.bind(locator, new HK2JerseyBinder()); 

Под капотом утилиты будут просто использовать службу динамической настройки.

Существует множество различных способов (динамического) добавления сервисов. Для получения дополнительной информации ознакомьтесь с документами. Еще одним хорошим источником информации является исходный код ServiceLocatorUtilities, на который я ссылался.

person Paul Samsotha    schedule 01.09.2017