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 а также @ServiceHK2 аннотаций.

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

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

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

1 ответ

Решение

Чтобы расширить комментарий Джвелла:

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 что я связан с.

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