Vertx + Jersey + HK2:使用@Contract 和@Service 自动绑定ServiceLocator

Vertx + Jersey + HK2: ServiceLocator autobindings using @Contract and @Service

我正在尝试利用 vertx-jersey 创建一个网络服务,我可以在其中注入我自己的自定义服务以及一些更标准的对象,例如 vertx 实例本身。

目前我正在像这样初始化网络服务器(即遵循 this example):

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 注释。

问题是我已经使用 ServiceLocatorUtilities 创建了 ServiceLocator,我在其中明确绑定了 HK2JerseyBinder,据我所知,我应该只创建一个 ServiceLocator 实例,其中所有内容都应为 accessible/bound.

我也知道我可以调用 ServiceLocatorUtilities.createAndPopulateServiceLocator(),但是看起来 JerseyServer 以及 HK2JerseyBinder 中绑定的所有其他内容都会被遗漏,因为它们不是没有注释。

有没有一种方法可以同时做到这两点或解决这个问题?

扩展 jwelll 的评论:

ServiceLocatorUtilities 顾名思义:它只是一个帮助创建 ServiceLocator 的实用程序。要在没有实用程序的情况下创建它,您可以使用 ServiceLocatorFactory。当您调用其中一个创建函数时,这就是该实用程序在幕后所做的事情。

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

当你想给locator动态添加服务时,可以使用DynamicConfigurationService,这是默认提供的服务。

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

此服务有一个 Populator,您可以获取并调用它 populate 方法,以使用您的 inhabitant files (you can get these with the generator) 中的服务填充定位器。

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

这是全部ServiceLocatorUtilities.createAndPopulateServiceLocator() does

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();

如果你想反过来做(populator first),你可以

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

在后台,实用程序将只使用动态配置服务。

有很多不同的方法可以(动态)添加服务。有关详细信息,请查看 the docs。另一个很好的信息来源是我链接到的 ServiceLocatorUtilities 的源代码。