2014-09-08 17 views
6

Vorrei creare un'istanza singleton di una classe che non è coinvolta in Jersey come risorsa o servizio e tuttavia vorrebbe che le sue dipendenze vengano iniettate dal ServiceLocator di Jersey.Come ottenere HK2 ServiceLocator in Jersey 2.12?

posso registrare manualmente questa classe nel mio costruttore ResourceConfig, il ResourceConfig viene quindi passato al metodo factory Grizzly in questo modo:

ResourceConfig resourceConfig = new DeviceServiceApplication(); 

LOGGER.info("Starting grizzly2..."); 
return GrizzlyHttpServerFactory.createHttpServer(BASE_URI, 
               resourceConfig, mServiceLocator); 

Il problema che rimane è come ottenere un riferimento al Jersey ServiceLocator quindi posso chiamare createAndInitialize() per ottenere il mio oggetto con le dipendenze iniettate. Vedo che nelle precedenti versioni di Jersey c'erano varianti di costruttori che si aspettavano un ApplicationHandler, che ovviamente fornisce l'accesso al localizzatore di servizi (il modo in cui inizializzo è un'altra questione). Puoi anche vedere che ho provato a passare in un ServiceLocator genitore, ma ovviamente la risoluzione si verifica da child -> localizzatore genitore e non nella direzione opposta, quindi chiedere al genitore il mio oggetto fallisce perché i tipi di Jersey @Contract e @Service non sono visibile qui.

Devo utilizzare qualcosa di diverso da GrizzlyHttpServerFactory? Devo rinunciare e collegare manualmente le dipendenze del mio singleton?

risposta

12

Sono stato in grado di ottenere un riferimento a ServiceLocator registrando uno ContainerLifecycleListener.

Nel metodo onStartup(Container container), chiamare container.getApplicationHandler().getServiceLocator().

Questo esempio memorizza il riferimento come variabile membro di ResourceConfig che è possibile utilizzare altrove tramite un accessorio.

class MyResourceConfig extends ResourceConfig 
{ 
    // won't be initialized until onStartup() 
    ServiceLocator serviceLocator; 

    public MyResourceConfig() 
    { 
     register(new ContainerLifecycleListener() 
     { 
      public void onStartup(Container container) 
      { 
       // access the ServiceLocator here 
       serviceLocator = container.getApplicationHandler().getServiceLocator(); 

       // ... do what you need with ServiceLocator ... 
       MyService service = serviceLocator.createAndInitialize(MyService.class); 
      } 

      public void onReload(Container container) {/*...*/} 
      public void onShutdown(Container container) {/*...*/} 
     }); 
    } 

    public ServiceLocator getServiceLocator() 
    { 
     return serviceLocator; 
    } 
} 

poi altrove:

MyService service 
    = myResourceConfig.getServiceLocator().createAndInitialize(MyService.class); 
+0

è questo l'unico modo? c'è qualche altro modo? l'accesso al ciclo di vita del contenitore sembra un eccessivo. Grazie – Architucas

+0

Un'altra soluzione alternativa è: https://stackoverflow.com/questions/21149161/jersey-and-hk2-servicelocator/21998307#21998307 – ozhan

+0

Che cos'è la configurazione della risorsa? e quando viene chiamata questa classe ad eccezione di 'myResourceConfig.getServiceLocator()'? –

Problemi correlati