2010-09-29 13 views
7

Sto creando una libreria che verrà inclusa come jar, quindi non conterrà un metodo main. Mi chiedo quale sia la procedura migliore per avviare Guice in questo caso. Ho un singleton di alto livello.Uso di Guice senza metodo principale

public class TestManager 
{ 
    private TestManager() 
    { 
    } 

    public static TestManager getInstance() 
    { 
     // construct and return singleton 
    } 

    public void createSomeObjects() 
    { 
    } 

} 

Dove devo eseguire il boot di Guice? Stavo pensando che nel costruttore potrei chiamare Guice.createInjector (new Module()); ma non inietterebbe nessuno degli oggetti creati in createSomeObjects().

C'è un modo comune per farlo quando non si dispone di un metodo main()?

Cheers.

risposta

8

Proprio come le configurazioni di registrazione, se questa è una vera biblioteca quindi le opzioni sono praticamente questa:

  • dire all'utente libreria che sono responsabili per l'avvio Guice stessi.
  • fornire un metodo di inizializzazione biblioteca che si prende cura di bootstrapping Guice, se vogliono utilizzare la libreria

Cercando di rendere la libreria super-intelligente da fare autoconfigurazione spesso finisce con un po 'inflessibile, rigido per testare le gerarchie di classi.

+5

Fornire ai client un modulo Guice potrebbe funzionare correttamente. –

+1

+1 per l'autoconfigurazione super-intelligente. Pensa a quanto è andato male con Apache Commons Logging. –

+0

@Jesse, non ho mai visto librerie che usano Guice internamente in realtà esporlo agli utenti finali. Ad esempio Maven e JIRA usano l'IoC dietro le quinte ma si iniettano nelle tue classi senza che tu sappia quale implementazione usano. Exposing Guice sembra più pulito (se l'utente è a suo agio con Guice) ma temo che possa spaventare gli utenti (perché altrimenti nessuno lo fa?). – Gili

0

Questo non è ciò che si dovrebbe fa, ma quello che si potrebbe cosa:

Let classi principali nella libreria ampliare o comunque fare riferimento a una classe che inizializza tutto in un blocco statico. Questo è un trucco molto sporco, ma se ti assicuri che la tua API non possa essere raggiunta senza che il classloader carichi la tua classe di inizializzatore, dovresti stare dalla parte della sicurezza.

Potresti renderlo un po 'più pulito se hai usato AspectJ e hai iniettato un membro privato del tipo di inizializzatore in tutte le classi della tua libreria (senza toccare il codice java), ma sarebbe comunque un trucco.

0

Se si sta usando Guice nell'ambito della libreria e non per l'intera applicazione, è possibile utilizzare un blocco statico nella classe TestManager.

Questa strategia presuppone che l'applicazione chiamerà TestManager.getInstance() ad un certo punto e che è l'unico punto di ingresso nell'API.

@Singleton 
class TestManager { 

    private static final TestManager INSTANCE; 

    static { 
    INSTANCE = Guice.createInjector(new Module()).getInstance(TestManager.class); 
    } 

    private TestManager() { 
    } 

    public static TestManager getInstance() { 
     return INSTANCE; 
    } 

    @Inject 
    public void createSomeObjects(YourDependencies ...) { 
    // Do something with dependencies 
    } 
}