I'm trying to make use of vertx-jersey to create a webservice in which I can inject my own custom services as well as some more standard object such as the vertx
instance itself.
At the moment I'm initialising the webserver like so (i.e. following 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();
});
The issue I'm having is that I also want to be able to make use of dependency injection so I can automatically wire up my other services using the @Contract
and @Service
HK2
annotations.
The issue is that I'm already creating the ServiceLocator
using the ServiceLocatorUtilities
in which I explicitly bind HK2JerseyBinder
and as I understand it I should only be creating a single ServiceLocator
instance in which everything should be accessible/bound.
I'm also aware that I could call ServiceLocatorUtilities.createAndPopulateServiceLocator()
instead, however it looks like the JerseyServer
along with everything else bound in HK2JerseyBinder
would then be missed out as they aren't annotated.
Is there a way that I can do both or work around this some how?
To expand on jwelll's comment:
The ServiceLocatorUtilities
is just what its name implies: it's just a utility to help create the ServiceLocator
. To create it without the utilities you would use the ServiceLocatorFactory
. This is what the utility does under the hood when you call one of its creation functions.
ServiceLocator locator = ServiceLocatorFactory().getInstance().create(null);
When you want to add services dynamically to locator, you can use the DynamicConfigurationService
, which is a provided service by default.
DynamicConfigurationService dcs = locator.getService(DynamicConfigurationService.class);
This service has a Populator
that you can get and call it populate
method for it to populate the locator with services from your inhabitant files (you can get these with the generator).
Populator populator = dcs.getPopulator();
populator.populate();
This is all the 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;
}
So since you already have an instance of the locator, all you need to do is get the dynamic configuration service, get the populator, and call its populate
method.
ServiceLocator locator = ServiceLocatorUtilities.bind(new HK2JerseyBinder());
DynamicConfigurationService dcs = locator.getService(DynamicConfigurationService.class);
Populator populator = dcs.getPopulator();
populator.populate();
And if you wanted to do it the other way around (populator first), you could do
ServiceLocator locator = ServiceLocatorUtilities.createAndPopulateServiceLocator();
ServiceLocatorUtilities.bind(locator, new HK2JerseyBinder());
Under the hood, the utilities will just use the dynamic configuration service.
There are a lot of different ways to (dynamically) add services. For more info, check out the docs. Another good source for information is the source code for the ServiceLocatorUtilities
that I linked to.