Spring è un framework di sviluppo Java open source leggero. Fornisce un modello completo di programmazione e configurazione per lo sviluppo di applicazioni Java a livello enterprise. Mira a semplificare lo sviluppo Java e aiuta gli sviluppatori a creare applicazioni in modo più efficace ed efficiente.
Spring si concentra su diverse aree di sviluppo delle applicazioni e offre un'ampia gamma di funzionalità come Dependency Injection e moduli pronti all'uso che sono:
- Spring MVC
- Spring JDBC
- Spring Web Flow
- Spring Security
- Spring ORM
- Spring AOP
- Spring Test
Questi moduli offrono migliori funzionalità per le applicazioni web e riducono drasticamente i tempi di sviluppo. Ad esempio, all'inizio dello sviluppo Web Java, dovevamo scrivere molto codice standard per inserire un record in una base dati. Utilizzando il JDBCTemplate del modulo Spring JDBC, possiamo ridurlo a poche righe di codice con semplici configurazioni.
Spring Boot è un'estensione di Spring, che elimina le configurazioni standard richieste per impostare un'applicazione Spring. Dotato di parte codice predefinito e configurazione basata su annotazioni, Spring Boot consente un ecosistema di sviluppo più rapido ed efficiente.
Poiché Spring Boot è costruito sulla base di Spring, offre tutte le funzionalità e i vantaggi di Spring. Spring Boot mira a ridurre la lunghezza del codice e offre agli sviluppatori il modo più semplice per creare un'applicazione.
Prima di tutto, diamo un'occhiata alle dipendenze minime richieste per creare un'applicazione web utilizzando Spring:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.18</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.18</version>
</dependency>
A differenza di Spring, Spring Boot richiede solo una dipendenza per far funzionare un'applicazione web:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.6.6</version>
</dependency>
Spring Boot offre anche una serie di dipendenze di avvio per i moduli Spring. Alcuni dei più popolari sono:
- spring-boot-starter-web
- spring-boot-starter-thymeleaf
- spring-boot-starter-data-jpa
- spring-boot-starter-aop
- spring-boot-starter-web-services
- spring-boot-starter-security
- spring-boot-starter-test
- spring-boot-starter-mail
Come suggerisce il nome, è un modulo del framework Spring che si occupa del Model-View-Controller, o pattern MVC. Quindi unisce tutti i vantaggi del modello MVC. Spring implementa MVC con il pattern del controller front usando il suo DispatcherServlet. In poche parole, il DispatcherServlet funge da controller principale per instradare le richieste alla destinazione prevista. Il modello non è altro che i dati della nostra applicazione e la vista è rappresentata da uno qualsiasi dei vari motori di modelli.
Nella fase iniziale di Model avviene la rappresentazione dei dati correlati alla logica di business. A questo punto seguono le operazioni di creazione dell’interfaccia utente e dell’esposizione dei dati, previste nella seconda fase del processo di View, per poi passare alla terza fase di Controller, la quale ha il compito di far combaciare, opportunamente, le due fasi precedenti.
Pertanto, all’interno di una applicazione Spring MVC si ritroveranno le medesime componenti di Model, View e Controller, secondo, però, una classificazione maggiormente specializzata:
– I Model vengono rappresentati dai gruppi, i quali, a loro volta, incarnano gli oggetti di gestione e le classi d’accesso ad ogni singolo database in funzione.
– Le View si rispecchiano all’interno dei vari file JSP (compilati, successivamente, in HTML) o anche da eventuali classi, idonee all’esportazione in formati diversi da HTML (PDF, XLS, CSV…).
– I Controller, per concludere, sono raggruppati in più classi (denominate Controllers) poste a stretto contatto con l’url e grazie alla correlazione fra Model e View, si occupano di gestire la richiesta dell’utente, gestore.
Per abilitare il supporto di Spring MVC tramite una classe di configurazione Java, tutto ciò che dobbiamo fare è aggiungere l' annotazione @EnableWebMvc:
@EnableWebMvc
@Configuration
public class WebConfig {
//TODO
}
Questo imposterà il supporto di base di cui abbiamo bisogno per un progetto MVC, come la registrazione di controller e mappature, convertitori di tipi, supporto di convalida, convertitori di messaggi e gestione delle eccezioni. Se invece vogliamo personalizzare questa configurazione, dobbiamo implementare l'interfaccia WebMvcConfigurer:
@EnableWebMvc
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
}
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver bean = new InternalResourceViewResolver();
bean.setViewClass(JstlView.class);
bean.setPrefix("/WEB-INF/view/");
bean.setSuffix(".jsp");
return bean;
}
}
In questo esempio, abbiamo registrato un bean ViewResolver che restituirà viste .jsp dalla directory /WEB-INF/view.
Molto importante quì è che possiamo registrare i controller di visualizzazione che creano una mappatura diretta tra l'URL e il nome della visualizzazione utilizzando ViewControllerRegistry. In questo modo, non c'è bisogno di alcun Controller tra i due.
Se vogliamo anche definire e scansionare le classi di controller, possiamo aggiungere l'annotazione @ComponentScan con il package che contiene i controller:
@EnableWebMvc
@Configuration
@ComponentScan(basePackages = { "com.saverioriotto.controller" })
public class WebConfig implements WebMvcConfigurer {
//TODO
}
Per avviare un'applicazione che carica questa configurazione, abbiamo anche bisogno di una classe di inizializzazione:
public class MainWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(final ServletContext sc) throws ServletException {
AnnotationConfigWebApplicationContext root =
new AnnotationConfigWebApplicationContext();
root.scan("com.saverioriotto");
sc.addListener(new ContextLoaderListener(root));
ServletRegistration.Dynamic appServlet =
sc.addServlet("mvc", new DispatcherServlet(new GenericWebApplicationContext()));
appServlet.setLoadOnStartup(1);
appServlet.addMapping("/");
}
}
Vediamo invece come implentare Controller e Viste:
@Controller
public class SampleController {
@GetMapping("/sample")
public String showForm() {
return "sample";
}
}
E la corrispondente risorsa .jsp, il file sample.jsp:
HELLO WORLD !
I file di visualizzazione basati su JSP si trovano nella cartella /WEB-INF del progetto, quindi sono accessibili solo all'infrastruttura Spring e non tramite accesso diretto quind da URL.
La differenza fondamentale nell'entry point di un'applicazione in Spring e Spring Boot risiede nel servlet. Spring utilizza web.xml o SpringServletContainerInitializer come punto di ingresso. D'altra parte, Spring Boot utilizza solo le funzionalità Servlet 3 per avviare un'applicazione. Vediamolo nel dettaglio:
Spring supporta sia il metodo di bootstrap legacy web.xml che l'ultimo metodo Servlet 3+.
Vediamo l'approccio web.xml nei seguenti passaggi:
- Il container del servlet (il server) legge il file web.xml.
- Il DispatcherServlet definito nel web.xml viene istanziato dal container.
- DispatcherServlet crea WebApplicationContext leggendo WEB-INF/{servletName}-servlet.xml.
- Infine, il DispatcherServlet registra i bean definiti nel contesto dell'applicazione.
Invece utilizzando l'approccio Servlet 3+ vediamo che:
- Il container cerca ede esgue le classi che implementano ServletContainerInitializer.
- SpringServletContainerInitializer trova tutte le classi che implementano WebApplicationInitializer.
- WebApplicationInitializer crea il contesto con classi XML o @Configuration.
- WebApplicationInitializer crea DispatcherServlet con il contesto creato in precedenza.
Viceversa per le applicazioni Spring Boot, per impostazione predefinita, utilizza un contaioner incorporato per eseguire l'applicazione. In questo caso, Spring Boot utilizza il Main principale per avviare un server Web incorporato. Si occupa anche dell'associazione dei bean Servlet, Filter e ServletContextInitializer dal contesto dell'applicazione al container servlet incorporato. Un'altra caratteristica di Spring Boot è che esegue automaticamente la scansione di tutte le classi nello stesso package o sotto-package della classe Main per i componenti.
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Inoltre, Spring Boot offre la possibilità di distribuirlo come archivio Web in un container esterno. In questo caso, dobbiamo estendere SpringBootServletInitializer:
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
//TODO
}
Quì il container servlet esterno cerca la classe Main definita nel file META-INF dell'archivio web e SpringBootServletInitializer si occuperà di associare Servlet, Filter e ServletContextInitializer.
Infine, vediamo come un'applicazione può essere impacchettata e distribuita. Entrambi questi framework supportano tecnologie di gestione dei pacchetti comuni come Maven e Gradle; tuttavia, questi framework differiscono molto, quando si tratta di distribuzione. Ad esempio, il plug-in Spring Boot Maven, che fornisce il supporto Spring Boot in Maven, consente di impacchettare jar eseguibili o archivi .war ed eseguire un'applicazione in "sul posto".
Alcuni dei vantaggi di Spring Boot rispetto a Spring nel contesto della distribuzione sono:
- Fornisce il supporto del container incorporato
- Possibilità di eseguire i jar in modo indipendente utilizzando il comando java -jar
- Opzione per escludere le dipendenze per evitare potenziali conflitti di jar durante la distribuzione in un container esterno
- Opzione per specificare i profili attivi durante la distribuzione
- Generazione di porte casuali per test di integrazione
Spring è una scelta eccellente per gli sviluppatori per creare applicazioni Java aziendali. Tuttavia, è molto vantaggioso se utilizzato insieme a Spring Boot. Mentre Spring offre agli sviluppatori flessibilità e versatilità, Spring Boot si concentra sulla riduzione della lunghezza e della configurazione del codice, fornendo così agli sviluppatori il metodo più semplice e veloce per creare un'applicazione. I vantaggi aggiuntivi di Spring Boot sono di grande valore in quanto riducono notevolmente i tempi e gli sforzi di sviluppo.