2017-08-27 4 views
0

J'essaie d'utiliser vertx-jersey pour créer un service web dans lequel je peux injecter mes propres services personnalisés ainsi que certains objets plus standard tels que le vertx instance lui-même.Vertx + Jersey + HK2: AutoBindings ServiceLocator utilisant @Contract et @Service

En ce moment je suis initialisant le serveur Web comme si (par exemple suivant 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(); 
}); 

La question que je vais avoir est que je veux aussi être en mesure d'utiliser l'injection de dépendance, donc je peut automatiquement câbler mes autres services en utilisant les @Contract et @ServiceHK2 annotations.

Le problème est que je crée déjà le ServiceLocator en utilisant le ServiceLocatorUtilities dans lequel je lie explicitement HK2JerseyBinder et si je comprends bien, je ne devrais créer une seule instance ServiceLocator où tout doit être accessible/lié.

Je suis également conscient que je pourrais appeler ServiceLocatorUtilities.createAndPopulateServiceLocator() à la place, mais il ressemble à JerseyServer avec tout le reste lié dans HK2JerseyBinder serait alors manqué car ils ne sont pas annotés.

Y a-t-il un moyen de faire les deux ou de contourner ce problème?

+1

Chaque ServiceLocator est associé à DynamicConfigurationService (https://javaee.github.io/hk2/apidocs/org/glassfish/hk2/api/DynamicConfigurationService.html). De cela, vous pouvez obtenir un Populator (https://javaee.github.io/hk2/apidocs/org/glassfish/hk2/api/Populator.html). Le populateur dispose de méthodes qui peuvent être utilisées pour ajouter dynamiquement des services à partir de (par exemple) des fichiers résidents ou de l'analyse de classe ou de tout autre mécanisme automatique que vous souhaitez utiliser pour découvrir des services. – jwells131313

Répondre

1

développiez commentaire de jwelll:

Le ServiceLocatorUtilities est exactement ce que son nom l'indique: il est juste un utilitaire pour aider à créer le ServiceLocator. Pour le créer sans les utilitaires, utilisez le ServiceLocatorFactory. C'est ce que l'utilitaire fait sous le capot lorsque vous appelez l'une de ses fonctions de création.

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

Lorsque vous voulez ajouter des services dynamiquement à locator, vous pouvez utiliser le DynamicConfigurationService, qui est un service fourni par défaut.

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

Ce service a une Populator que vous pouvez obtenir et appeler la méthode populate pour elle pour alimenter le localisateur des services de votre inhabitant files (vous pouvez obtenir ces avec le generator).

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

Ceci est tous les 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; 
} 

Donc, puisque vous avez déjà une instance du localisateur, tout ce que vous devez faire est d'obtenir le service de configuration dynamique, obtenir le populator et appeler sa méthode populate.

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

Et si vous vouliez le faire dans l'autre sens (populator premier), vous pouvez le faire sous le capot

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

, les services publics vont simplement utiliser le service de configuration dynamique.

Il existe de nombreuses façons d'ajouter (dynamiquement) des services.Pour plus d'informations, consultez the docs. Une autre bonne source d'information est le code source pour le ServiceLocatorUtilities auquel j'ai lié.