Che cosa fa il framework Spring? Dovrei usarlo? Perché o perché no?

230

Quindi, sto iniziando un nuovo progetto in Java e sto pensando di utilizzare Spring. Perché sto considerando la primavera? Perché molte persone mi dicono che dovrei usare Spring! Seriamente, ogni volta che ho cercato di convincere la gente a spiegare che cos'è esattamente Spring o cosa fa, non possono mai darmi una risposta diretta. Ho controllato le introduzioni sul sito SpringSource, e sono davvero complicate o veramente focalizzate sul tutorial, e nessuna di loro mi dà una buona idea del perché dovrei usarla, o di come mi renderà la vita più facile. A volte le persone gettano il termine "iniezione di dipendenza", che mi confonde ancora di più, perché penso di avere una diversa comprensione di cosa significhi questo termine.

Comunque, ecco un po 'del mio background e della mia app:

Da tempo si sta sviluppando in Java, facendo lo sviluppo web di back-end. Sì, faccio un sacco di test unitari. Per facilitare questo, in genere creo (almeno) due versioni di un metodo: uno che utilizza le variabili di istanza e uno che utilizza solo le variabili passate nel metodo. Quello che usa le variabili di istanza chiama l'altro, fornendo le variabili di istanza. Quando arriva il momento del test unitario, utilizzo Mockito per simulare gli oggetti e quindi effettuare chiamate al metodo che non usa variabili di istanza. Questo è quello che ho sempre capito "iniezione di dipendenza".

La mia app è piuttosto semplice, da una prospettiva CS. Piccolo progetto, 1-2 sviluppatori per iniziare. Principalmente operazioni di tipo CRUD con una serie di ricerche gettate dentro. Fondamentalmente un gruppo di servizi web RESTful, oltre a un front-end Web e poi eventualmente alcuni client mobili. Sto pensando di fare il front-end in HTML / CSS / JS / JQuery, quindi non ho intenzione di usare JSP. Usare Hibernate come ORM e Jersey per implementare i servizi web.

Ho già iniziato a programmare e sono davvero desideroso di ottenere una demo là fuori che possa guardarmi intorno e vedere se qualcuno vuole investire. Quindi ovviamente il tempo è essenziale. Capisco che Spring abbia abbastanza la curva di apprendimento, inoltre sembra che richieda un sacco di configurazioni XML, che in genere cerco di evitare come la peste. Ma se può rendere la mia vita più facile e (soprattutto) se renderla può rendere lo sviluppo e test più veloce, sono disposto a mordere il proiettile e imparare Spring.

Quindi per favore. Educami Dovrei usare la primavera? Perché o perché no?

    
posta sangfroid 12.07.2011 - 20:54
fonte

7 risposte

105

What does the Spring framework do? Should I use it? Why or why not?

Spring è un framework che ti aiuta a "collegare" diversi componenti insieme. È molto utile nei casi in cui si hanno molti componenti e si potrebbe decidere di combinarli in modi diversi, oppure si desidera semplificare lo scambio di un componente con un altro a seconda delle diverse impostazioni o ambienti.

This is what I've always understood "dependency injection" to be.

Suggerirei una definizione diversa:

"Progetta i tuoi oggetti in modo che facciano affidamento su una forza esterna per fornire loro ciò di cui hanno bisogno, aspettandosi che queste dipendenze siano sempre iniettate prima che qualcuno le chieda loro per iniziare a fare i loro soliti lavori. "

Confrontalo con questo: "Ogni oggetto è responsabile di uscire e trovare tutto e tutti quelli di cui ha bisogno all'avvio."

it looks like it necessitates a whole bunch of XML configuration

Bene, la maggior parte delle cose su XML (o basate su annotazioni) sta dicendo cose come:

  • Quando qualcuno chiede "HammerStore", voglio che tu crei un'istanza di example.HammerStore e la restituisca. Cache l'istanza per la prossima volta, dal momento che deve esserci solo un negozio.
  • Quando qualcuno chiede "SomeHammer", voglio che ti chieda un "HammerStore" e restituisca il risultato del metodo makeHammer() del negozio. non memorizza nella cache questo risultato.
  • Quando qualcuno chiede "SomeWrench", voglio che tu crei un'istanza di example.WrenchImpl , Usa l'impostazione di configurazione gaugeAmount e inseriscila nella proprietà setWrenchSize() dell'istanza. Non memorizzare nella cache il risultato.
  • Quando qualcuno chiede "LocalPlumber", voglio creare un'istanza di example.PlumberImpl . Metti la stringa "Pedro" nel suo metodo setName() , metti un "SomeHammer" nel suo metodo setHammer() e metti un "SomeWrench" nel suo metodo setWrench() . Restituisce il risultato e memorizza il risultato nella cache in un momento successivo poiché è necessario un solo idraulico.

In questo modo, Spring consente ai componenti di connettersi, etichettarli, controllarne il ciclo di vita / memorizzazione nella cache e alterare il comportamento in base alla configurazione.

To facilitate [testing] I typically make (at least) two versions of a method : one that uses instance variables, and one that only uses variables that are passed in to the method.

Sembra un sacco di spese generali per non avere molti benefici per me. Invece, imposta le tue variabili di istanza protected o visibilità del pacchetto e individua l'unità prova all'interno dello stesso pacchetto com.mycompany.whatever . In questo modo puoi controllare e modificare le variabili di istanza quando vuoi durante il test.

    
risposta data 13.07.2011 - 21:40
fonte
64

Innanzitutto, cos'è l'iniezione di dipendenza?

Semplice. Hai una classe, ha un campo privato (impostato su null) e dichiari un setter pubblico che fornisce il valore per quel campo. In altre parole, la dipendenza della classe (il campo) viene iniettata da una classe esterna (tramite il setter). Questo è tutto. Niente di magico.

Secondo, Spring può essere utilizzato senza XML (o molto poco)

Se ti immergi con Spring 3.0.5.GA o superiore, puoi utilizzare il supporto per l'integrazione delle dipendenze da JDK6 +. Ciò significa che puoi collegare dipendenze usando le annotazioni @Component e @Resource .

Perché usare Spring a tutti?

Ovviamente, l'iniezione di dipendenza promuove test unitari molto semplici poiché tutte le tue classi hanno setter per le dipendenze importanti e queste possono essere facilmente derise usando il tuo framework di simulazione preferito per fornire il comportamento richiesto.

A parte questo, Spring fornisce anche molti modelli che fungono da classi base per rendere l'uso delle tecnologie standard JEE un gioco da ragazzi con cui lavorare. Ad esempio, JdbcTemplate funziona bene con JDBC, JpaTemplate fa buoni affari con JPA, JmsTemplate rende JMS piuttosto semplice. Il RestTemplate è semplicemente fantastico nella sua semplicità. Ad esempio:

RestTemplate restTemplate = new RestTemplate();
MyJaxbObject o = restTemplate.getForObject("https://secure.example.org/results/{param1}?param2={param2}",MyJaxbObject.class,"1","2");

e il gioco è fatto. I parametri vengono iniettati e devi solo fornire annotazioni JAXB per MyJaxbObject. Questo non dovrebbe richiedere tempo se li hai generati automaticamente da un XSD usando il plugin Maven JAXB. Si noti che non c'è stato alcun casting in corso, né è stato necessario dichiarare un marshaller. È tutto fatto per te.

Potrei gettare per sempre sulle meraviglie di Spring, ma forse la cosa migliore da fare è provare un semplice picco di codice nel tentativo di collegare un servizio web RESTful per estrarre i dati da un DAO iniettato che supporta le transazioni.

    
risposta data 12.07.2011 - 22:40
fonte
28

Prima di tutto, la tua comprensione dell'iniezione di dipendenza non è fondamentalmente sbagliata, ma piuttosto diversa da ciò che la maggior parte della gente intende quando usa il termine. Quello che descrivi è un modo piuttosto strano e non convenzionale per raggiungere la testabilità. Ti consiglio di allontanarti da questo, poiché gli altri sviluppatori saranno piuttosto sconcertati da quel tipo di codice.

L'iniezione delle dipendenze come generalmente intesa (e implementata da Spring) significa che le dipendenze di una classe (ad esempio un'origine dati JDBC) non vengono recuperate dalla classe stessa, ma "iniettate" da un contenitore quando viene creata l'istanza. Quindi non hai due versioni di ogni metodo che utilizza l'origine dati; al contrario, si ha una configurazione di iniezione delle dipendenze in cui viene iniettata l'origine dati "reale" e una in cui viene iniettata una simulazione. Oppure, se l'iniezione avviene tramite il costruttore o un getter, il codice di test può eseguire l'iniezione in modo esplicito.

In secondo luogo, Spring non è solo un'iniezione di dipendenza, anche se questa è la sua funzionalità principale. Fornisce anche transazioni dichiarative, pianificazione del lavoro, autenticazione e una serie di altre funzionalità (incluso un framework web MVC completo) che potrebbe essere necessario. Esistono altri framework che forniscono la stessa funzionalità, ma a parte Spring, solo Java EE li ha tutti integrati.

    
risposta data 12.07.2011 - 23:34
fonte
19

Perché vuoi usare Spring, puoi leggerlo su link

In breve:

  • Le applicazioni J2EE tendono a contenere quantità eccessive di "impianti idraulici" codice. Molte revisioni di codice rivelano ripetutamente un'alta percentuale di codice che non fa nulla: codice di ricerca JNDI, oggetti di trasferimento, prova / cattura i blocchi per acquisire e rilasciare le risorse JDBC. . . . scrittura e il mantenimento di tale codice idraulico dimostra un notevole drenaggio delle risorse che dovrebbe essere focalizzato sul dominio aziendale dell'applicazione.

  • Molte applicazioni J2EE usano un modello a oggetti distribuiti dove questo è non appropriato. Questa è una delle principali cause di codice eccessivo e duplicazione del codice. È anche concettualmente sbagliato in molti casi; le applicazioni distribuite internamente sono più complesse di quelle co-localizzate applicazioni e spesso molto meno performante. Certo, se il tuo i requisiti aziendali dettano un'architettura distribuita, è necessario implementare un'architettura distribuita e accettarne il trade-off incorre (e Spring offre funzionalità per aiutare in tali scenari). Ma non dovresti farlo senza un motivo valido.

  • Il modello del componente EJB è eccessivamente complesso. EJB è stato concepito come un modo di ridurre la complessità quando si implementa la business logic in J2EE applicazioni; in pratica non è riuscito a questo scopo.

  • EJB è abusato. EJB è stato essenzialmente progettato internamente distribuito, applicazioni transazionali. Mentre quasi tutto non banale le applicazioni sono transazionali, la distribuzione non dovrebbe essere integrata il modello di base del componente.

  • Molti "modelli di progettazione J2EE" non sono, in effetti, modelli di progettazione, ma soluzioni alternative per i limiti della tecnologia. Uso eccessivo della distribuzione e l'uso di API complesse come EJB ha generato molti dubbi modelli di progettazione; è importante esaminarli in modo critico e guardare per approcci più semplici, più produttivi.

  • Le applicazioni J2EE sono difficili da testare. Le API J2EE e in particolare, il modello del componente EJB, è stato definito prima dell'agile il movimento è decollato. Pertanto il loro design non tiene conto della facilità di test unitari. Attraverso entrambe le API e i contratti impliciti, lo è sorprendentemente difficile da testare le applicazioni basate su EJB e molti altre API J2EE all'esterno di un server applicazioni. Eppure i test unitari al di fuori di un server di applicazioni è essenziale per ottenere un test elevato copertura e riprodurre molti scenari di errore, come la perdita di connettività a un database. È anche vitale per garantire che i test può essere eseguito rapidamente durante lo sviluppo o il processo di manutenzione, riducendo al minimo i tempi improduttivi in attesa di ridistribuzione.

  • Alcune tecnologie J2EE hanno semplicemente fallito. Il principale autore di reati qui è un bean di entità, che si è dimostrato poco efficace per disastroso produttività e nei loro vincoli sull'orientamento agli oggetti.

risposta data 15.07.2011 - 13:02
fonte
13

What does the Spring framework do?

La primavera è come non solo oggi, ciò che era noto come un quadro semplice, è un ecosistema completo.

Argomenti trattati dall'ecosistema primaverile:

  • Spring Framework (ad esempio Dipendenza dell'iniezione, AOP ...)

  • Spring Cloud

  • Dati primaverili

  • Spring Security

  • Spring Batch

  • Social di primavera

Vedi qui per una copertura completa dell'ecosistema. È possibile selezionare i progetti in modo che tu possa utilizzare Google Guice per DI e ad es. Spring Security per gestire le questioni relative alla sicurezza. Non è necessario acquistare nell'intero ecosistema.

Lo stesso framework Spring copre oggi principalmente

  • Iniezione di dipendenza

  • Programmazione orientata agli aspetti inclusa la gestione dichiarativa delle transazioni di Spring

  • Applicazione web MVC di primavera e framework dei servizi Web RESTful

  • Supporto di base per JDBC, JPA, JMS

Fonte spring.io

In generale, si potrebbe dire che Spring è una raccolta di pattern e pratiche implementati nel codice, che potrebbero aiutare a migliorare o accelerare il ciclo di sviluppo delle applicazioni.

Per quello che è (il core-framework) è più conosciuto è la sua capacità nel campo dell'iniezione delle dipendenze . Spring ha, come si chiama Inversion of control container o short Contenitore IoC o ancora più corto il contenitore (per il quale" spring "viene talvolta usato anche).

Che cos'è l'iniezione di dipendenza?

Iniezione di dipendenza significa che il tuo oggetto riceve ogni dipendenza da altri oggetti tramite un meccanismo esternalizzato.

Dì, hai una macchina, il modo tipico, è implementato è:

public class Car {

    Engine e;

    public Car() { 
        e = new Engine(); 
    }

}

L'oggetto della macchina dipende da un motore. Poiché il motore è implementato come membro della macchina, non può essere scambiato per es. un motore di prova.

Ora entra in gioco l'iniezione di dipendenza :

public class Car {

    Engine e;

    public Car(Engine e) { 
        this.e = e; 
    }

}

Dopo, puoi cambiare i motori. Quello che vedi qui sopra è chiamato injection injection . Ci sono altri tipi come ad es. setter -iniezione o metodo -iniezione. In che modo la primavera ti aiuta con questo? Spring consente di contrassegnare i componenti da iniettare con l'annotazione @Autowired e esegue automaticamente il cablaggio dell'oggetto injecteed - è probabile che il componente che si desidera iniettare abbia delle dipendenze. Iniettabili - per così dire - sono contrassegnati tramite @Component

public class Car {

    Engine e;

    @Autowired
    public Car(Engine e) { 
        this.e = e; 
    }

}

Ma questa è solo una delle tante funzioni che Spring ha da offrire.

Should I use Spring? Why or why not?

Poiché la primavera non è molto invadente e offre molti aiuti, dovresti prendere in considerazione l'utilizzo della primavera. Soprattutto per i nuovi progetti, Spring Boot è molto interessante. start.spring.io offre un'interfaccia point'n'click facile da usare per generare un modello di progetto per iniziare. È anche possibile utilizzare curl per recuperare un modello:

curl start.spring.io

  .   ____          _            __ _ _
 /\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _' | \ \ \ \
 \/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

:: Spring Initializr ::  https://start.spring.io

This service generates quickstart projects that can be easily customized.
Possible customizations include a project's dependencies, Java version, and
build system or build structure. See below for further details.

The services uses a HAL based hypermedia format to expose a set of resources
to interact with. If you access this root resource requesting application/json
as media type the response will contain the following links:
+-----------------+-----------------------------------------+
| Rel             | Description                             |
+-----------------+-----------------------------------------+
| gradle-build    | Generate a Gradle build file            |
| gradle-project  | Generate a Gradle based project archive |
| maven-build     | Generate a Maven pom.xml                |
| maven-project * | Generate a Maven based project archive  |
+-----------------+-----------------------------------------+

...

D'altra parte, framework come spark o dropwizard offre anche un buon punto di partenza per la creazione rapida di app Web.

    
risposta data 15.06.2015 - 13:35
fonte
12

Prima eravamo soliti scrivere applicazioni web e servizi semplici, efficienti, veloci usando solo Java, Servlet e JSP, html e xml, JDBC API. E 'stato abbastanza buono; JUnit era un buon strumento da testare. Abbiamo riposato facilmente che il nostro codice ha funzionato.

Hibernate è arrivato per semplificare SQL e abilitare il vero mapping delle tabelle del database con oggetti Java, consentendo alle relazioni gerarchiche di riflettersi nel Mapping delle relazioni oggettuali o nell'ORM come lo chiamiamo. Lo amavo. Soprattutto, non è stato necessario mappare il ResultSet su un oggetto o tipo di dati Java.

Sono arrivati i puntini per aggiungere il pattern Model View Controller alle nostre app Web, era buono.

Gli EJB erano un enorme sovraccarico e il dolore e le annotazioni rendevano il codice simile al graffio di un pollo e ora la primavera è arrivata su di noi gente innocente. Mi sembra esagerato.

Ad esempio, ora impacchettiamo il nostro semplice URL jdbc, user, passiamo prima in jdbc.properties, poi in hibernate properties second e poi in spring bean per la terza volta!

Contro tutto questo, prendere in considerazione l'idea di ottenere una connessione dove ne hai bisogno è davvero semplice come mostrato di seguito in puro java, che è quello che stiamo realmente facendo dopo aver passato tutta quella roba con Spring:

Connection connection = DriverManager.getConnection(url, user, pass);

Questo è di per sé auto-esplicativo che è un grande giro intorno e avvolge in tondo e intorno per fare una cosa semplice, veloce e facile, senza altri grandi vantaggi. È come avvolgere tonnellate e tonnellate di carta regalo attorno a un piccolo bel regalo che è tutto ciò che si tiene davvero comunque.

Un altro esempio è un aggiornamento batch. Con Spring è complicato coinvolgere alcune classi e interfacce prima di poter utilizzare JdbcTemplate per eseguire un aggiornamento in batch. Con jdbc semplice è semplicemente:

Statement statement = connection.createStatement();
statement.addBatch(sqlquery);
statement.executeBatch();

Non può essere più semplice o più veloce di così.

Non supporto questo framework. Scusate. Chi diavolo vuole iniezioni ogni volta che hanno bisogno di qualcosa?

    
risposta data 15.06.2012 - 11:04
fonte
4

È un framework scritto in Java con un sacco di cose incluse per rendere funzionale la tua applicazione web (ad esempio il supporto per l'internazionalizzazione). Fornisce anche un buon modo per strutturare l'applicazione in livelli. Usalo, ti farà risparmiare un sacco di tempo a lungo termine.

Un buon libro per conoscere Spring è: MVC Spring Expert e flusso web

    
risposta data 12.07.2011 - 21:13
fonte

Leggi altre domande sui tag