2009-12-30 21 views
9

Possibili duplicati:
What is dependency injection?
What exactly is Spring for?A proposito di Dipendenza da iniezione e Spring Framework?

Voglio sapere Che cosa è Spring Framework? Perché e quando si dovrebbe usarlo nello sviluppo di Java Enterprise? La risposta sarebbe "Un quadro di iniezione delle dipendenze". Va bene, quali vantaggi abbiamo quando si utilizzano i quadri di iniezione delle dipendenze? L'idea di descrivere classi con valori setter e/o parametri di costruzione mi sembra strana. Perché farlo? Perché possiamo modificare le proprietà senza ricompilare il progetto? È tutto ciò che otteniamo?

Quindi, quali oggetti dovremmo descrivere in beans.xml? Tutti gli oggetti o solo alcuni?

Le risposte più semplici sono i benvenuti

+3

Quindi quello che stai cercando è un articolo sull'argomento, non una risposta SO. – Bozho

+0

Non sto cercando un articolo sull'argomento QUANTO HO GIÀ PROVATO I MIGLIORI LIBRI pubblicati sull'argomento. Voglio conoscere l'opinione di chi lo usa nel lavoro di tutti i giorni. – EugeneP

+0

Bene, funziona. –

risposta

18

Usiamo Dependency Injection (DI) per implementare sciolto accoppiamento. La scelta di ogni particolare contenitore DI non è così importante.

Ogni volta che si crea un'istanza di una classe utilizzando la parola chiave new, è strettamente paio il codice per quella classe, e non sarà in grado di sostituire che l'attuazione particularl con uno diverso (almeno non senza ricompilare il codice).

Questo sarebbe simile a questo in C# (ma sarebbe equivalente in Java):

public class MyClass 
{ 
    public string GetMessage(int key) 
    { 
     return new MessageService().GetMessage(key) 
    } 
} 

Questo significa che se si desidera in seguito desidera utilizzare un MessageService diverso, non si può.

D'altra parte, se si inserisce un'interfaccia nella classe e si aderisce allo Liskov Substition Principle, sarà possibile variare il consumatore e il servizio in modo indipendente.

public class MyClass 
{ 
    private readonly IMessageService messageService; 

    public MyClass(IMessageService messageService) 
    { 
     if(messageService == null) 
     { 
      throw new ArgumentNullException("messageService"); 
     } 

     this.messageService = messageService; 
    } 

    public string GetMessage(int key) 
    { 
     return this.messageService.GetMessage(key) 
    } 
} 

Sebbene questo sembra più complicato, abbiamo ora riusciti a seguire il Single Responsibility Principle garantendo che ciascun collaboratore fa solo una cosa, e che possiamo variare sia indipendentemente l'uno dall'altro.

Inoltre, ora è possibile modificare il comportamento di MyClass senza modificare la classe stessa, aderendo così allo Open/Closed Principle.

11

riconfigurazione è sopravvalutato. La cosa più importante che si ottiene usando DI è testability. Poiché le tue classi non dipendono dalle implementazioni ma dalle astrazioni, puoi sostituirle con mock/stub nei tuoi test di unità.

Esempio

Senza DI:

class SaleAction{ 

private BillingService billingService; 

public SaleAction(){ 
    billingService = new CreditCardService(); //dependency is hardcoded 
} 

public void pay(long amount){ 
    //pre payment logic 
    billingService.pay(amount); 
    //post payment logic 
} 

} 

In questo esempio, si supponga di voler test di unità logica logica e post-pagamento il pagamento anticipato di SaleAction ... non è possibile perché è SaleAction accoppiato a CreditCardService e probabilmente eseguendo i test genererà pagamenti falsi.

Ora lo stesso esempio con DI:

class SaleAction{ 

    private BillingService billingService; 

    public SaleAction(BillingService service){ 
     billingService = service; //DI 
    } 

    public void pay(long amount){ 
     //pre payment logic 
     billingService.pay(amount); 
     //post payment logic 
    } 

    } 

Ora SaleAction è disaccoppiato da qualsiasi applicazione, il che significa che nel test si può fare SaleAction action = new SaleAction(new DummyBillingService());.

Speranza che aiuta, c'è anche il articolo su DI, scritto da Martin Fowler che si può trovare here

+0

effettivamente stai dicendo che i quadri DI, ad es. La primavera è sopravvalutata poiché è banale sostituire le dipendenze con i mock nel codice senza un framework.la creazione di quei burloni può essere piuttosto complicata, ma non vedo alcun vantaggio nel poterli scambiare dentro e fuori con mock alternativi. –

+4

non fare affidamento su implementazioni concrete è al centro di OOP, non solo di DI. – Bozho

+0

Non dico che le strutture siano sopravvalutate. DI è obbligatorio per il test dell'unità e il test dell'unità è obbligatorio per lo sviluppo del software. –

1

Opinione: capire quale problema si prova a risolvere con DI e adottare un framework che si adatti meglio. La primavera potrebbe aggiungere molta complessità al tuo problema.

(Uno dei first articles about DI by Martin Fowler. Penso che il termine è stato coniato DI in questo articolo.)

3

La primavera si è trasformata in un'enorme struttura, che potrebbe essere fonte di confusione se si sta solo cercando di avvolgere la propria attenzione sull'iniezione di dipendenza. Il progetto Google Guice è minuscolo e funziona solo con puro Java, senza XML e senza extra. C'è un bel video introduttivo che spiega anche DI. http://code.google.com/p/google-guice/

+0

@Ken Fox. No, no. Userò la primavera. DI è stato menzionato perché costituisce la base del Framework di primavera. Non mi interessa il DI, mi interessa principalmente la funzionalità di Spring. ma ho bisogno di sapere cosa giace nella base. – EugeneP

+1

La primavera è sempre stata una struttura enorme, molto più di DI. AOP ha avuto la stessa fatturazione dal primo giorno, così come le librerie. Dire che Spring e Guice mappa one-to-one è sbagliato come dire lo stesso per Spring MVC e Struts. La primavera include funzionalità equivalenti a entrambe e molto altro. – duffymo

+0

@Ken Fox. Va bene, non capisco ancora AOP, ho letto che si tratta di "problemi trasversali", cose come la registrazione che si verificano praticamente in ogni metodo della classe. Ma dimmi, va bene, c'è AOP. Ma non sostituisce DI, vero? – EugeneP

2

Penso di poter prendere una crepa alla domanda, anche se non sono sicuro che qualsiasi risposta sarà soddisfacente.

La risposta più semplice è che la primavera è una combinazione di tecnologie:

  1. iniezione di dipendenza, che utilizza il principio di Hollywood per aiutare a mantenere l'interfaccia e l'implementazione separata;
  2. programmazione orientata all'aspetto, che isola i problemi trasversali in moduli che è possibile applicare in modo dichiarativo. Il "ciao mondo" di AOP sta registrando, ma è tutto su Spring (ad esempio transazioni, proxy dinamici per servizi remoti, sicurezza, ecc.). Pensate ai filtri servlet e avrete l'idea;
  3. librerie per aiutare con compiti comuni come persistenza (JDBC, Hibernate, iBatis, JDO, JPA, ecc.), Remoting (RMI, HTTP, servizi Web), asynch messaging (POJOs guidati dai messaggi), validazione e binding, web MVC (Spring or Struts), utilità come e-mail, pianificazione, sicurezza, ecc.

Ma la risposta più profonda è che si ottiene il beneficio dell'esperienza di Rod Johnson come consulente su progetti Java EE. Ha distillato ciò che ha funzionato per lui nei suoi concerti in Interface 21/Spring, e ora puoi avere il vantaggio di tutto ciò gratuitamente.

Il team Spring scrive codice che è stato progettato, testato e segue gli standard in modo più rigoroso di qualsiasi altro che scriverò mai. (Immaginate Juergen Hoeller che abbaia Rod Johnson perché il suo codice non ha rispettato lo standard prima del check-in.) Posso contare sul loro codice quadro quando lo uso e mi concentro sul mio problema aziendale. Non scrivo più e più volte il codice della piastra della caldaia.

Per me, Spring è più un modello architettonico che funge da guida per la creazione di applicazioni Web.Alcune persone potrebbero dire che è troppo ingegnerizzato, e per alcuni problemi sono corretti, ma per il tipo di problemi con cui mi trovo di fronte regolarmente Spring è solo un biglietto.

Per quanto riguarda i subquestions:

Quali vantaggi cosa abbiamo quando si utilizza quadri iniezione di dipendenza?

Gli oggetti non devono essere responsabili della gestione delle loro dipendenze. Il contesto applicativo di Spring è in realtà solo un grande Factory Pattern del GoF. Ti incoraggia a progettare un'interfaccia in modo da poter modificare l'implementazione secondo necessità. La tua interfaccia di persistenza potrebbe utilizzare un'implementazione JDBC oggi, Hibernate domani; potresti decidere di generare automaticamente un proxy per gestire il suo comportamento transazionale. Nessuno codice client deve essere modificato se si esegue il codice su un'interfaccia.

L'idea di descrivere classi con valori setter e/o parametri di costruzione mi sembra strana. Perché farlo? Perché possiamo modificare le proprietà senza ricompilare il progetto ? È tutto ciò che otteniamo?

Strano? Non usi proprietà o costruttori nel tuo codice? Lo fai perché è così che viene scritta la maggior parte delle classi Java. Spring usa semplicemente quei meccanismi come un modo per fornire dipendenze alla classe.

Quindi, quali oggetti dovremmo descrivere in beans.xml? Tutti gli oggetti o solo alcuni?

Solo i bean con dipendenze. Io chiamo ancora "nuovo" per oggetti che sono locali per un particolare metodo. Vengono creati, utilizzati e raccolti nella portata del metodo. Questi non devono essere sotto il controllo di Spring.

+0

Non posso dire che la tua risposta copre tutte le mie sotto-domande, ma comunque è stato interessante leggerlo. +1 – EugeneP

+0

Verifica se le aggiunte sono migliori. – duffymo

1

Ecco uno good video dato da Bob Lee e due dei suoi studi su Guice (Guice è un framework di distribuzione delle dipendenze come Spring). I primi 10 minuti circa spiegano perché Guice (o iniezione di dipendenza) sarebbe meglio dell'alternativa (Fabbriche), quindi non si tratta solo di Guice.

2

hai già alcune buone risposte qui, voglio affrontare un paio di specifiche domande che avete:

L'idea di descrivere le classi con i valori setter e/o parametri del costruttore sembra strano per me. Perché farlo? Perché possiamo modificare le proprietà senza ricompilare il progetto? È tutto ciò che otteniamo?

Sembra strano in un primo momento, ma il punto è che il contenitore si occupa di collegare le dipendenze per gli oggetti, gli oggetti stessi non sono responsabili di questo. L'ambito degli oggetti configurati in bean.xml è gestito da Spring, quindi non dobbiamo preoccuparci tanto delle cose che vengono istanziate senza le giuste dipendenze (a patto che la configurazione sia corretta, sono stato conosciuto per scrivere test unitari per verificare che la configurazione di primavera sta facendo quello che voglio a.)

Allora, quali oggetti dovremmo descrivere a beans.xml? Tutti gli oggetti o solo alcuni?

I tipi di oggetti descritti in beans.xml sono per lo più componenti - i controllori, i servizi, gli oggetti di accesso ai dati, e le cose che hanno bisogno come gestori di transazioni, ibernazione fabbriche di sessione, fonti di dati, cose del genere. Gli oggetti di dominio vengono in genere recuperati da oggetti di accesso ai dati o istanziati direttamente, perché non hanno dipendenze da nient'altro che altri oggetti di dominio (o su classi di utilità che sono ancora più indipendenti delle classi di dominio).

1

Forse non dovresti tentare di intraprendere lo "sviluppo di impresa Java" senza un'idea dei problemi di architettura e progettazione di base? Ti suggerisco di trovare un collega esperto che è disposto ad aiutarti, o di investire qualche sforzo in più nella lettura di quei libri, o comunque seguire un corso.

In ogni caso, non esiste una "risposta semplice" alla tua domanda.

0

Iniezione di dipendenza è una soluzione alternativa per le classi virtuali mancanti!

 

NB: se non si sa che cosa le classi virtuali sono, si prega di fare riferimento a "Virtual classes, anyone?".

+1

L'orrore dell'eredità virtuale multipla C++ sarà con me per sempre. Mi piace quell'articolo, ma hai bisogno di un nuovo nome. I framework DI ora usano le annotazioni in modo che siano quasi indistinguibili da una caratteristica linguistica - fino a quando due strutture diverse si scontrano e l'illusione viene distrutta. –