2009-12-24 21 views

risposta

14

Se ServiceLoader si adatta in gran parte alle vostre esigenze, questo significa che state cercando l'individuazione dei servizi tramite la presenza di file sul percorso della classe. Questa è solo una piccola parte di ciò che OSGi fornisce.

OSGi consente di installare in modo dinamico bundle, pubblicizzare servizi, revocare pubblicità e disinstallare i pacchetti tutto mentre l'applicazione è in esecuzione. Inoltre, come consumatore di servizi, è possibile consultarli con entusiasmo, filtrando le query preliminari, e rilevare quando i fornitori di servizi offerti vanno e vengono. Questi pacchetti non devono necessariamente trovarsi sul percorso della classe e possono essere forniti in varie forme; I file Jar e "directory esplose" sono i due che ricordo.

Al contrario, ServiceLoader fa solo una cosa: espone le fabbriche individuabili. Generalmente si crea un'interfaccia di tipo factory che richiede alcuni argomenti per decidere se quel provider può offrire il servizio appropriato, ad esempio mappando un determinato nome di set di caratteri a CharsetDecoder. Non esiste un protocollo formalizzato per l'acquisizione e il rilascio di un servizio da tale fornitore. OSGi formalizza il legame e lo slegamento dei consumatori ai servizi. Il consumatore può ricevere una notifica quando nuovi fornitori arrivano online e il fornitore può ricevere una notifica quando un consumatore acquisisce e rilascia un'istanza di servizio. Se questo controllo del ciclo di vita è importante per il tuo servizio e perdi OSGi, dovrai costruirlo tu stesso; ServiceLoader non arriva così lontano.

In alternativa, piuttosto che la ricerca e l'utilizzo di servizi desiderosi, è possibile adottare un approccio passivo e dichiarativo e consentire ad uno dei responsabili delle dipendenze OSGi di soddisfare le esigenze dichiarate con i fornitori di servizi disponibili. Ci sono molti manager delle dipendenze tra cui scegliere. Spring Dynamic Modules è uno dei più capaci.

OSGi offre molti altri servizi "middleware". Non cercherò di venderti su di loro qui, poiché la tua domanda si concentra principalmente su ciò che ti mancherebbe scegliendo ServiceLoader.

+0

Grazie - è sempre difficile sapere cosa sia OSGi.No, ho davvero bisogno solo di quello che ha ServiceLocator e apprezzo che sia integrato. Ero solo sospettoso, non ne avevo sentito parlare prima che pensassi che fosse malato o qualcosa del genere. –

+2

Uso 'ServiceLoader' su un progetto corrente e le uniche frustrazioni che ho trovato sono 1) con la necessità di spingere le estensioni come file Jar sul percorso della classe (le nostre applicazioni non incoraggiano l'utente finale a manipolare il percorso della classe) e 2) l'ordine non specificato con il quale i fornitori di pari livello della stessa interfaccia di servizio saranno esposti a un consumatore. Quest'ultimo rende difficile incorporare una "priorità", come quella che le estensioni fornite dall'utente dovrebbero essere preferibili ai servizi di base dell'applicazione. Di conseguenza, 'ServiceLoader' viene utilizzato al meglio quando i provider non si sovrappongono o competono tra loro. – seh

3

Come fa notare, se sei interessato solo alla scoperta di servizi semplice, ServiceLoader è un modo leggero per separare i consumatori dai fornitori. Ma non offre alcuna assistenza con i servizi di composizione insieme.

Ad esempio, supponiamo che il servizio A debba utilizzare il servizio B. Si tratta di una "dipendenza del servizio" ... ma cosa dovrebbe fare A se B non è disponibile? In OSGi possiamo organizzare che se B non è disponibile, allora neanche A sarà - assumendo che la dipendenza sia obbligatoria; possiamo anche supportare dipendenze opzionali. D'altro canto, quando si utilizza ServiceLoader, il servizio A non ha alcun controllo sulla sua disponibilità fintanto che il JAR che lo racchiude si trova sul classpath ... quindi deve fornire la sua funzionalità anche in assenza dei servizi "back-end" richiesti.

Un'altra cosa da tenere a mente con ServiceLoader è cercare di astrarre il meccanismo di ricerca. Il meccanismo di pubblicazione è abbastanza carino, pulito e dichiarativo. Ma la ricerca (tramite java.util.ServiceLoader) è brutta quanto l'inferno, implementata come uno scanner di classpath che si interrompe orribilmente se si inserisce il codice in qualsiasi ambiente (come OSGi o Java EE) che non ha visibilità globale. Se il tuo codice si aggroviglia, allora ti sarà difficile eseguirlo su OSGi più tardi. Meglio scrivere un'astrazione che puoi sostituire quando sarà il momento.

+1

È possibile elaborare un'astrazione semplice per ServiceLoader che renderebbe più semplice la migrazione a OSGi in seguito. Al momento dispongo di un framework diviso in 12 o 13 file jar che utilizza il meccanismo serviceloader per il componente principale per "analizzare" i moduli sul classpath. Vorrei che il framework funzionasse bene in OSGi in futuro ma non dipendesse da OSGi. Finora, non riesco a vedere come raggiungere la dualità. È persino possibile essere mezzo dentro e mezzo fuori da OSGi quando si utilizza il meccanismo ServiceLoader? – Chris

+1

La migliore astrazione sarebbe qualcosa come l'iniezione di dipendenza. Nel tuo codice che richiede qualche servizio "Foo", non provare a cercare quel servizio ma semplicemente permetterlo di essere iniettato attraverso un metodo setFoo(). Da qualche altra classe, effettua la chiamata a ServiceLoader per ottenere un'istanza di Foo e inserirla nel codice che ne ha bisogno. Se successivamente si passa a OSGi, è sufficiente eliminare la seconda classe e utilizzare Servizi dichiarativi o Blueprint per gestire l'iniezione di servizi OSGi. –

Problemi correlati