ROME 27-28 march 2015
Java EE facile con Spring Boot
l.bennardis@email.it
Luigi Bennardis
ROME 27-28 march 2015 - Luigi Bennardis
Agenda
 Le caratteristiche di Spring Boot
 La soluzione applicativa
 Descrizione
 Tecnologie integrate
 Ambiente di sviluppo
 Implementazione
 Conclusioni
 Appendice: JAX-RS (Jersey) & JSR 330
 Link
ROME 27-28 march 2015 - Luigi Bennardis
Le caratteristiche di Spring Boot
 Semplificazione dello sviluppo applicativo basato su SPRING
• realizzare soluzioni eseguibili in modalità stand-alone e/o in container J2EE
 Applicazione del Paradigma «convention over configuration»
• Semplificazione dello sviluppo senza ricadute sulla flessibilità
• Eliminazione dei file di configurazione
 Vista semplificata di Spring
 Numerose funzionalità di default facilmente sostituibili
 Annotazioni speciali
 Gestione semplificata delle dipendenze
 Inclusione del container di esecuzione
 «Auto-Configurazione» delle librerie di dipendenza
ROME 27-28 march 2015 - Luigi Bennardis
La soluzione applicativa: descrizione
Servizio Web di prenotazione di esami universitari
 Componenti
 REST Controller: tecnologia di esposizione del servizio web & BL
 Service Facade: espone funzioni a grana grossa
 Data Persistence: espone funzioni a grana fine di persistenza dati
 Message Queue: espone funzioni a grana fine di scrittura di messaggi
ROME 27-28 march 2015 - Luigi Bennardis
La soluzione applicativa: tecnologie integrate
 Servlet Container in modalità embedded
 Tomcat 8
 Undertow 1.1
 Application Server – Java EE
 Tomcat EE 2.0
 HornetQ – JMS
 Sistema di messaggistica asincrona open source
 Implementa la specifica JMS
 Server/Integrato in AS J2EE/Embedded
 H2 – JDBC
 Database open source – Java
 Bassa impronta binaria
 Server/In memory/Embedded
ROME 27-28 march 2015 - Luigi Bennardis
La soluzione applicativa: tecnologie integrate
 Hibernate – ORM – JPA
 Framework di ORM (Object Relational Mapping)
 Implementa la specifica JPA
 Realizza la persistenza sul protocollo JDBC
 Atomikos – JTA
 Open Source Transaction Manager
 Realizza la transazionalità distribuita XA (JDBC-JMS)
 Cloud Foundry
 Progetto Open Source di “Open Cloud”
 Deliver di piattaforme applicative come servizi (PAAS)
 Semplifica: distribuzione/esecuzione/scalabilità
ROME 27-28 march 2015 - Luigi Bennardis
La soluzione applicativa: ambiente di sviluppo
 Java JDK 1.8
 Spring (Luna) – STS (Spring Tool Suite)
 Maven 3
 Spring Boot 1.2 (<Spring-Boot-Starter>)
 Servlet 3.1
 Java Transaction Api
 Deployment su AS EE (Tomcat EE 2.0)
 Eclipse Cloud Foundry Integration
ROME 27-28 march 2015 - Luigi Bennardis
La soluzione applicativa: implementazione
 Embedding del servlet container
 Integrazione H2 Hibernate e JSR 250
 Integrazione HornetQ
 Deploy su Application Server EE (Tomcat EE)
 Integrazione Atomikos, transazionalità distribuita
 Deploy su Cloud Foundry
ROME 27-28 march 2015 - Luigi Bennardis
<!– PLUG-IN BOOT PER MAVEN -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- DEFAULT TOMCAT 8.0 EMBEDDED + SPRING MVC-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- UNDERTOW EMBEDDED-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
Maven: plugin per Spring Boot e dichiarazione delle dipendenze
Implementazione → Embedding del container
ROME 27-28 march 2015 - Luigi Bennardis
@SpringBootApplication // @Configuration @EnableAutoConfiguration @ComponentScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@SpringBootApplication
Corrisponde alle annotazioni di Spring:
@Configuration @EnableAutoConfiguration @ComponentScan
Deve essere definita in un package di root
Esegue l’auto-configurazione delle librerie dichiarate nel classpath
Esegue la scansione del package per rilevare automaticamente le classi da
iniettare nel contesto di Spring
SpringApplication:
Iniezione di argomenti da linea di comando
Classe di avvio Spring-Boot da linea di comando
Implementazione → Embedding del container
ROME 27-28 march 2015 - Luigi Bennardis
@RestController //@Controller @ResponseBody
public class Controller {
@RequestMapping("/prenotaEsame")
public String servletTest(
@RequestParam(value="matricola") String matricola,
@RequestParam(value="esame") String esame)
{
return "Servlet eseguita param: codice esame: " + esame + " matricola studente: " +
matricola ;
}
}
@RestController
Marca la classe come Web Controller. Corrisponde alle annotazioni
@Controller: gestisce la Request HTTP
@ResponseBody: indirizza il valore di ritorno a una Web Response
@RequestMapping
Mappa la Web Request “/<url>” sul metodo “servletTest”
@RequestParam
Mappa i valori dei parametri della Request sulle variabili di firma del metodo
RestController : classe che gestisce Request e Response HTTP
Implementazione → Embedding del container
ROME 27-28 march 2015 - Luigi Bennardis
mvn spring-boot:run
Esecuzione da Eclipse (Tomcat embedded) e console
.....
Tomcat initialized with port(s): 8080 (http)
Starting service Tomcat
Starting Servlet Engine: Apache Tomcat/8.0.20
Initializing Spring embedded WebApplicationContext
Root WebApplicationContext: initialization completed in 2014 ms
Mapping servlet: 'dispatcherServlet' to [/]
.....
Mapped
"{[/prenotaEsame],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}"
onto public java.lang.String
it.luigibennardis.boot.demo.rest.Controller.servletTest(java.lang.String,java.lang.St
ring)
.....
Tomcat started on port(s): 8080 (http)
Started Application in 3.942 seconds (JVM running for 8.652)
.....
Initializing Spring FrameworkServlet 'dispatcherServlet'
FrameworkServlet 'dispatcherServlet': initialization started
FrameworkServlet 'dispatcherServlet': initialization completed in 32 ms
Implementazione → Embedding del container
Eclipse: Run & Console
ROME 27-28 march 2015 - Luigi Bennardis
mvn spring-boot:run
Esecuzione da Eclipse (Undertow embedded) e console
.....
Undertow started on port(s) 8080 (http)
Started Application in 3.942 seconds (JVM running for 8.652)
.....
Initializing Spring FrameworkServlet 'dispatcherServlet'
FrameworkServlet 'dispatcherServlet': initialization started
FrameworkServlet 'dispatcherServlet': initialization completed in 32 ms
Implementazione → Embedding del container
Eclipse: Run & Console
ROME 27-28 march 2015 - Luigi Bennardis
<!-- JAVA PERSISTENCE API SUPPORT -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- H2 DATABASE -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<spring-boot-starter-data-jpa>
Configura la specifica JPA nel contesto di Spring
<h2>
Configura un datasource per l’istanza H2 eseguita in modalità
embedded
Maven: dichiarazione delle dipendenze
Implementazione → H2 - Hibernate
ROME 27-28 march 2015 - Luigi Bennardis
@Service
public class ServicePrenotazioneEsame {
private final IRepositoryPrenotazioneEsame prenEsameRepo;
@Autowired
public ServicePrenotazioneEsame(
IRepositoryPrenotazioneEsame localRepo) {
this.prenEsameRepo = localRepo;
}
public void registraPrenotazione(String codPrenotazione, String codEsame, String matricolaStud) {
this.prenEsameRepo.save(new EntityPrenotazioneEsame(codPrenotazione, codEsame, matricolaStud));
}
}
@Service
Business Service Facade che incapsula le funzioni di grana fine esponendo alla
logica applicativa quelle a grana più grossa
@Autowired
Inietta la classe marcata nel contesto Spring
Service Facade:
metodo di registrazione della prenotazione
Implementazione → H2 - Hibernate
ROME 27-28 march 2015 - Luigi Bennardis
@RestController
public class Controller {
@Autowired
private ApplicationContext context;
@RequestMapping("/prenotaEsame")
public String prenotaEsame(@RequestParam(value="matricola") String matricola,@RequestParam(value="esame")
String esame)
{
ServicePrenotazioneEsame service = context.getBean(ServicePrenotazioneEsame.class);
IRepositoryPrenotazioneEsame repository = context.getBean(IRepositoryPrenotazioneEsame.class);
service.registraPrenotazione(codPrenotazione, esame, matricola); }
@RequestMapping("/prenotazioniFatte")
public String prenotazioniFatte()
{
IRepositoryPrenotazioneEsame repository = context.getBean(IRepositoryPrenotazioneEsame.class);
return "PRENOTAZIONI PRESENTI IN BASE DATI: " + " <BR> " + repository.count() + " <BR> " +
repository.findAll(); }
}
Controller:
chiamata al metodo esposto dal Service Facade
Implementazione → H2 - Hibernate
ROME 27-28 march 2015 - Luigi Bennardis
@Component
public class UnitTestCaricaTipologiche {
private final IRepositoryEsame esameRepo;
@Autowired
public UnitTestCaricaTipologiche(IRepositoryEsame localRepo) {
this.esameRepo = localRepo;
}
@PostConstruct // ANNOTAZIONE JSR 250 (SPECIFICA JAVA EE 5) ESEMPIO DI HOOK DEL CICLO DI VITA.
public void inizializzaBaseDati() throws Exception {
System.out.println("INIZIALIZZAZIONE TABELLA TIPOLOGICA ESAME");
this.esameRepo.save(new EntityEsame("00001", "Ingegneria Civile"));
this.esameRepo.save(new EntityEsame("00002", "Ingegneria Elettronica"));
this.esameRepo.save(new EntityEsame("00003", "Ingegneria Meccanica"));
this.esameRepo.save(new EntityEsame("00004", "Ingegneria Informatica"));
System.out.println("TABELLA TIPOLOGICA ESAME->
INIZIALIZZAZIONE COMPLETA RECORD: " + esameRepo.count());
}
}
@PostConstruct
Marca il metodo ehe la classe esegue dopo essere stata istanziata
H2 Emdedded -> JSR 250 LIFECICLE HOOKS
Gestione dell’Inizializzazione del database (UT/IT)
Implementazione → H2 - Hibernate
ROME 27-28 march 2015 - Luigi Bennardis
.....
.....
Building JPA container EntityManagerFactory for persistence unit 'default'
HHH000204: Processing PersistenceUnitInfo [
.....
.....
HHH000412: Hibernate Core {4.3.8.Final}
HHH000206: hibernate.properties not found
HHH000021: Bytecode provider name : javassist
HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
HHH000397: Using ASTQueryTranslatorFactory
HHH000227: Running hbm2ddl schema export
HHH000230: Schema export complete
INIZIALIZZAZIONE TABELLA TIPOLOGICA ESAME
TABELLA TIPOLOGICA ESAME-> INIZIALIZZAZIONE COMPLETA RECORD: 4.....
.....
Esecuzione da Eclipse e console di output
Implementazione → H2 - Hibernate
mvn spring-boot:run
Eclipse: Run & Console
ROME 27-28 march 2015 - Luigi Bennardis
<!-- SPRING JMS -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
</dependency>
<!-- HORNETQ -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hornetq</artifactId>
</dependency>
<dependency>
<groupId>org.hornetq</groupId>
<artifactId>hornetq-jms-server</artifactId>
</dependency>
<!-- TOMEE EXTERNAL -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!– PACKAGING J2EE-->
<packaging>war</packaging>
Maven: dichiarazione delle dipendenze e packaging J2EE
Implementazione → HornetQ
ROME 27-28 march 2015 - Luigi Bennardis
@SpringBootApplication
public class Application extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
@SpringBootServletInitializer
Inizializza il contesto Spring-Boot nel Container J2EE
Esecuzione di Spring Boot nel servlet container J2EE
Implementazione → HornetQ
ROME 27-28 march 2015 - Luigi Bennardis
package it.luigibennardis.boot.demo.rest;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
@Component
public class CodaPrenotazioneEsame {
@JmsListener(destination = "codaPrenotazioneEsami")
public void onMessage(String content) {
System.out.println("MESSAGGIO PUBBLICATO SULLA CODA codaPrenotazioneEsami :" + content);
}
}
spring.hornetq.mode=embedded
spring.hornetq.embedded.enabled=true
spring.hornetq.embedded.queues=codaPrenotazioneEsami
@Component
Marca la classe per essere iniettata nel contesto di Spring in fase di scansione
del classpath
@JmsListener
Marca il metodo che corrisponde al target del listener JMS
Listener JMS: implementazione
Implementazione → HornetQ
HornetQ: direttive di configurazione
ROME 27-28 march 2015 - Luigi Bennardis
@Service
public class ServicePrenotazioneEsame {
//.....
@Autowired
public ServicePrenotazioneEsame(IRepositoryPrenotazioneEsame localRepo,JmsTemplate jmsTemplate) {
this.prenEsameRepo = localRepo;
this.jmsTemplate = jmsTemplate;
}
public void registraPrenotazione(String codPrenotazione, String codEsame, String matricolaStud) {
//PERSISTENZA DEI DATI SUL DATABASE
this.prenEsameRepo.save(new EntityPrenotazioneEsame(codPrenotazione, codEsame, matricolaStud));
//PUBBLICAZIONE DEL MESSAGGIO SULLA CODA
this.jmsTemplate.convertAndSend("codaPrenotazioneEsami", codPrenotazione + "|" + codEsame + "|" +
matricolaStud);
}
}
Service Facade:
chiamata al metodo di scrittura del messaggio
Implementazione → HornetQ
ROME 27-28 march 2015 - Luigi Bennardis
mvn spring-boot: repackage
java -jar targetdemo-spring-boot-h2embHibJmsJta-0.0.1-SNAPSHOT.war
.....
HQ221000: live server is starting with configuration HornetQ Configuration
(clustered=false,backup=false
HQ221045: libaio is not available, switching the configuration into NIO
HQ221043: Adding protocol support CORE
HQ221003: trying to deploy queue jms.queue.codaPrenotazioneEsami
HQ221007: Server is now live
HQ221001: HornetQ Server version 2.4.5.FINAL (Wild Hornet, 124) [f9175388-bb5f-11e4-88d9-
5bae268d51f1]
.....
.....
MESSAGGIO PUBBLICATO SULLA CODA codaPrenotazioneEsami :PRE00001|abcd0001|000001
MESSAGGIO PUBBLICATO SULLA CODA codaPrenotazioneEsami :PRE00001|abcd0003|000001
MESSAGGIO PUBBLICATO SULLA CODA codaPrenotazioneEsami :PRE00001|abcd0005|000001
.....
Distribuzione su TOMEE e console di output
Implementazione → HornetQ
Command Line: Run & Console
ROME 27-28 march 2015 - Luigi Bennardis
<!-- TRANSAZIONALITA' ATOMIKOS -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>
<spring-boot-starter-jta-atomikos>
Definisce la dipendenza alle librerie di Atomikos e auto-
configura il container di esecuzione con le funzioni di
transazionalità
Maven: dichiarazione delle dipendenze
Implementazione → H2 - Atomikos
ROME 27-28 march 2015 - Luigi Bennardis
@Service
@Transactional
public class ServicePrenotazioneEsame {
//……
public void registraPrenotazione(String codPrenotazione, String codEsame, String matricolaStud) {
//PERSISTENZA DEL RECORD SUL DATABASE
this.prenEsameRepo.save(new EntityPrenotazioneEsame(codPrenotazione, codEsame, matricolaStud));
//PUBBLICAZIONE DEL MESSAGGIO SULLA CODA
this.jmsTemplate.convertAndSend("codaPrenotazioneEsami", codPrenotazione + "|" + codEsame + "|" +
matricolaStud);
if (codEsame.equals("ROLLBACK_SIMULATO")) {
//ECCEZIONE->ROLLBACK TRANSAZIONE
throw new RuntimeException("SIMULAZIONE DI ROLLBACK ULTIMA TRANSAZIONE");
}
}
@Transactional
• Marca in modo dichiarativo i confini della transazionalità
• Eccezione fake per eseguire il rollback
Service facade:
codifica della direttiva JTA
Implementazione → Atomikos
ROME 27-28 march 2015 - Luigi Bennardis
mvn spring-boot:repackage
java -jar target/demo-spring-boot-h2embHibJmsJta-0.0.1-SNAPSHOT.war
Esecuzione da command line e console
Implementazione → Atomikos
Command Line: Run & Console
.....
.....
No properties path set - looking for transactions.properties in classpath...
transactions.properties not found - looking for jta.properties in classpath...
Failed to open transactions properties file - using default values
Using JTA UserTransaction: com.atomikos.icatch.jta.UserTransactionManager@bb479
Using JTA TransactionManager:
com.atomikos.icatch.jta.UserTransactionManager@bb479
.....
.....
MESSAGGIO PUBBLICATO SULLA CODA codaPrenotazioneEsami :PROGRESSIVO MESSAGGIO IN
CODA 1|PRE00001|abcd0001|000001
MESSAGGIO PUBBLICATO SULLA CODA codaPrenotazioneEsami :PROGRESSIVO MESSAGGIO IN
CODA 2|PRE00001|abcd0002|000001
SIMULAZIONE DI ROLLBACK ULTIMA TRANSAZIONE
ROME 27-28 march 2015 - Luigi Bennardis
<plugin>
<groupId>org.cloudfoundry</groupId>
<artifactId>cf-maven-plugin</artifactId>
<version>1.0.1</version>
<configuration>
<server>pivotal-cloud-foundry</server>
<target>https://api.run.pivotal.io</target>
<org>luigibennardis.it</org>
<space>development</space>
<appname>demoSpringBoot</appname>
<url>demoSpringBoot.cfapps.io</url>
<memory>1024</memory>
</configuration>
</plugin>
Maven: plug-in deploy Cloud Foundry
Implementazione → Cloud Foundry
ROME 27-28 march 2015 - Luigi Bennardis
cf:push -Dcf.username=l.bennardis@email.it -Dcf.password=password
.....
[INFO] Creating application 'demoSpringBoot'
[INFO] Uploading 'C:developmentEclipseWKS05-demo-spring-boot-
h2embHibJmsTransactionalCFtargetdemo-spring-boot-h2embHibJmsJtaCf-0.0.1-SNAPSHOT.war'
[INFO] Starting application
[INFO] -----> Downloaded app package (29M)
-----> Java Buildpack Version: v2.7.1 | https://github.com/cloudfoundry/java-buildpack#fee275a
-----> Downloading Open Jdk JRE 1.8.0_40 from
https://download.run.pivotal.io/openjdk/lucid/x86_64/openjdk-1.8.0_40.tar.gz (2.6s)
Expanding Open Jdk JRE to .java-buildpack/open_jdk_jre (1.3s)
----->
-----> Downloading Spring Auto Reconfiguration 1.7.0_RELEASE from
https://download.run.pivotal.io/auto-reconfiguration/auto-reconfiguration-1.7.0_RELEASE.jar
(0.1s)
-----> Uploading droplet (73M)
[INFO] Checking status of application 'demoSpringBoot'
[INFO] 0 of 1 instances running (1 starting)
[INFO] .....
[INFO] 1 of 1 instances running (1 running)
Maven: deploy & console
Implementazione → Cloud Foundry
ROME 27-28 march 2015 - Luigi Bennardis
Gestione dell’istanza
Implementazione → Cloud Foundry
Cloud Foundry: Tail Log - Scale up & Console
ROME 27-28 march 2015 - Luigi Bennardis
Implementazione → Cloud Foundry
Gestione dell’istanza con il Plug-in di Eclipse
ROME 27-28 march 2015 - Luigi Bennardis
Gestione dell’istanza con il Plug-in di Eclipse
Implementazione → Cloud Foundry
ROME 27-28 march 2015 - Luigi Bennardis
Conclusioni
 Rapido sviluppo di applicazioni basate su Spring
 Vista semplificata dell’ecosistema Spring e delle dipendenze
 Auto-configurazione dell’applicazione in base alle librerie dichiarate nel classpath:
 H2->datasource+embedding
 Hibernate->JPA provider
 Progressivo «scale-up» dei componenti «auto-configurati» con versioni più robuste
 Soddisfazione di requisiti non funzionali comuni a molti progetti
 Copertura di una significativa area del ciclo di vita
 Costi ridotti in fase di start-up
 Nessuna gestione degli ambienti di run-time (SO/Mware)
 Nessuna configurazione server side
 Nessun «middleware» installato o da gestire
 Flessibilità ed efficienza del deployment
 Software design che abilita al Cloud (PAAS)
 Altri: Sicurezza, metriche, esternalizzazione di configurazioni
ROME 27-28 march 2015 - Luigi Bennardis
Appendice: JAX-RS (JERSEY) & JSR 330
 Soluzione presentata: Spring-Boot -> RESTFull Web Service basato su Spring:
 stack completo comprendente MVC, REST, ecc.
 annotazioni potenti (Dependency & Context Injection) ma proprietarie Spring.
 Evoluzione della soluzione: Spring-Boot -> RESTFull Web Service basato su Jersey & JSR-330
 Jersey: framework OS per realizzare Web Services RESTful attraverso API Java JAX-RS
 JSR-330: specifica Java per il Contexts and Dependency Injection le piattaforme Java EE.
 Iniezione di un Java Bean: @Autowired (Spring) -> @Inject (JSR-330)
 Dichiarazione di un Java Bean: @Component(Spring) -> @Named(JSR-330)
ROME 27-28 march 2015 - Luigi Bennardis
@SpringBootApplication
public class Application {
@Named
public static class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
this.register(Controller.class);
}
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@Named
Dichiarazione di iniezione di un Java Bean nel contesto in fase di scansione del
classpath
Classe Java per eseguire Spring-Boot con Jersey
Implementazione JAX-RS: JERSEY- JSR330
ROME 27-28 march 2015 - Luigi Bennardis
@Named
@Transactional
public class ServicePrenotazioneEsame {
@Inject
private JmsTemplate jmsTemplate;
@PersistenceContext
private EntityManager entityManager;
public void registraPrenotazione(String codPrenotazione, String codEsame, String matricolaStud) {
//PERSISTENZA DATI SUL DATABASE
this.entityManager.persist(new EntityPrenotazioneEsame(codPrenotazione, codEsame, matricolaStud));
//PUBBLICAZIONE MESSAGGIO SULA CODA
this.jmsTemplate.convertAndSend("codaPrenotazioneEsami","PROGRESSIVO MESSAGGIO IN CODA "+
counter.incrementAndGet( )+ "|" + codPrenotazione + "|" + codEsame + "|" + matricolaStud);
@Inject
Punto di iniezione di un Java Bean: non sono necessari set/get
Service Facade: annotazioni JSR-330
Implementazione JAX-RS: JERSEY- JSR330
ROME 27-28 march 2015 - Luigi Bennardis
@Named
@Path("/prenotaEsameTest")
@Produces(MediaType.TEXT_HTML)
public class Controller {
@Inject
private ServicePrenotazioneEsame service;
@GET
@Path("/infoPrenota")
public Response get(@QueryParam("codiceEsame") String codiceEsame,
@QueryParam("matricolaStudente") String matricolaStudente) {
//…………
try {
service.registraPrenotazione("aa00099",codiceEsame, matricolaStudente);
esitoPrenotazione = "ESEGUITA";
}
//………… }
@GET
Metodo Get della request HTTP
@Path
Definisce la corrispondenza della risorsa (sub-risorsa) alla classe (metodo)
Controller REST: annotazioni Jersey
Implementazione JAX-RS: JERSEY- JSR330
ROME 27-28 march 2015 - Luigi Bennardis
Link
 https://github.com/lbennardis/Codemotion15SpringBoot (codice sorgente)
 http://projects.spring.io/spring-boot/ (Spring-Boot)
 http://tomee.apache.org/ (Tomcat EE)
 http://cloudfoundry.org/index.html (Cloud Foundry)
 https://jersey.java.net/ (Jersey)
 https://jcp.org/en/jsr/detail?id=330 (JSR-330)
 https://jcp.org/en/jsr/detail?id=250 (JSR-250)
ROME 27-28 march 2015 - Luigi Bennardis
Leave your feedback on Joind.in!
https://joind.in/event/view/3347

Java EE facile con Spring Boot - Luigi Bennardis - Codemotion Roma 2015

  • 1.
    ROME 27-28 march2015 Java EE facile con Spring Boot l.bennardis@email.it Luigi Bennardis
  • 2.
    ROME 27-28 march2015 - Luigi Bennardis Agenda  Le caratteristiche di Spring Boot  La soluzione applicativa  Descrizione  Tecnologie integrate  Ambiente di sviluppo  Implementazione  Conclusioni  Appendice: JAX-RS (Jersey) & JSR 330  Link
  • 3.
    ROME 27-28 march2015 - Luigi Bennardis Le caratteristiche di Spring Boot  Semplificazione dello sviluppo applicativo basato su SPRING • realizzare soluzioni eseguibili in modalità stand-alone e/o in container J2EE  Applicazione del Paradigma «convention over configuration» • Semplificazione dello sviluppo senza ricadute sulla flessibilità • Eliminazione dei file di configurazione  Vista semplificata di Spring  Numerose funzionalità di default facilmente sostituibili  Annotazioni speciali  Gestione semplificata delle dipendenze  Inclusione del container di esecuzione  «Auto-Configurazione» delle librerie di dipendenza
  • 4.
    ROME 27-28 march2015 - Luigi Bennardis La soluzione applicativa: descrizione Servizio Web di prenotazione di esami universitari  Componenti  REST Controller: tecnologia di esposizione del servizio web & BL  Service Facade: espone funzioni a grana grossa  Data Persistence: espone funzioni a grana fine di persistenza dati  Message Queue: espone funzioni a grana fine di scrittura di messaggi
  • 5.
    ROME 27-28 march2015 - Luigi Bennardis La soluzione applicativa: tecnologie integrate  Servlet Container in modalità embedded  Tomcat 8  Undertow 1.1  Application Server – Java EE  Tomcat EE 2.0  HornetQ – JMS  Sistema di messaggistica asincrona open source  Implementa la specifica JMS  Server/Integrato in AS J2EE/Embedded  H2 – JDBC  Database open source – Java  Bassa impronta binaria  Server/In memory/Embedded
  • 6.
    ROME 27-28 march2015 - Luigi Bennardis La soluzione applicativa: tecnologie integrate  Hibernate – ORM – JPA  Framework di ORM (Object Relational Mapping)  Implementa la specifica JPA  Realizza la persistenza sul protocollo JDBC  Atomikos – JTA  Open Source Transaction Manager  Realizza la transazionalità distribuita XA (JDBC-JMS)  Cloud Foundry  Progetto Open Source di “Open Cloud”  Deliver di piattaforme applicative come servizi (PAAS)  Semplifica: distribuzione/esecuzione/scalabilità
  • 7.
    ROME 27-28 march2015 - Luigi Bennardis La soluzione applicativa: ambiente di sviluppo  Java JDK 1.8  Spring (Luna) – STS (Spring Tool Suite)  Maven 3  Spring Boot 1.2 (<Spring-Boot-Starter>)  Servlet 3.1  Java Transaction Api  Deployment su AS EE (Tomcat EE 2.0)  Eclipse Cloud Foundry Integration
  • 8.
    ROME 27-28 march2015 - Luigi Bennardis La soluzione applicativa: implementazione  Embedding del servlet container  Integrazione H2 Hibernate e JSR 250  Integrazione HornetQ  Deploy su Application Server EE (Tomcat EE)  Integrazione Atomikos, transazionalità distribuita  Deploy su Cloud Foundry
  • 9.
    ROME 27-28 march2015 - Luigi Bennardis <!– PLUG-IN BOOT PER MAVEN --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <!-- DEFAULT TOMCAT 8.0 EMBEDDED + SPRING MVC--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- UNDERTOW EMBEDDED--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-undertow</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> </dependency> Maven: plugin per Spring Boot e dichiarazione delle dipendenze Implementazione → Embedding del container
  • 10.
    ROME 27-28 march2015 - Luigi Bennardis @SpringBootApplication // @Configuration @EnableAutoConfiguration @ComponentScan public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } @SpringBootApplication Corrisponde alle annotazioni di Spring: @Configuration @EnableAutoConfiguration @ComponentScan Deve essere definita in un package di root Esegue l’auto-configurazione delle librerie dichiarate nel classpath Esegue la scansione del package per rilevare automaticamente le classi da iniettare nel contesto di Spring SpringApplication: Iniezione di argomenti da linea di comando Classe di avvio Spring-Boot da linea di comando Implementazione → Embedding del container
  • 11.
    ROME 27-28 march2015 - Luigi Bennardis @RestController //@Controller @ResponseBody public class Controller { @RequestMapping("/prenotaEsame") public String servletTest( @RequestParam(value="matricola") String matricola, @RequestParam(value="esame") String esame) { return "Servlet eseguita param: codice esame: " + esame + " matricola studente: " + matricola ; } } @RestController Marca la classe come Web Controller. Corrisponde alle annotazioni @Controller: gestisce la Request HTTP @ResponseBody: indirizza il valore di ritorno a una Web Response @RequestMapping Mappa la Web Request “/<url>” sul metodo “servletTest” @RequestParam Mappa i valori dei parametri della Request sulle variabili di firma del metodo RestController : classe che gestisce Request e Response HTTP Implementazione → Embedding del container
  • 12.
    ROME 27-28 march2015 - Luigi Bennardis mvn spring-boot:run Esecuzione da Eclipse (Tomcat embedded) e console ..... Tomcat initialized with port(s): 8080 (http) Starting service Tomcat Starting Servlet Engine: Apache Tomcat/8.0.20 Initializing Spring embedded WebApplicationContext Root WebApplicationContext: initialization completed in 2014 ms Mapping servlet: 'dispatcherServlet' to [/] ..... Mapped "{[/prenotaEsame],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String it.luigibennardis.boot.demo.rest.Controller.servletTest(java.lang.String,java.lang.St ring) ..... Tomcat started on port(s): 8080 (http) Started Application in 3.942 seconds (JVM running for 8.652) ..... Initializing Spring FrameworkServlet 'dispatcherServlet' FrameworkServlet 'dispatcherServlet': initialization started FrameworkServlet 'dispatcherServlet': initialization completed in 32 ms Implementazione → Embedding del container Eclipse: Run & Console
  • 13.
    ROME 27-28 march2015 - Luigi Bennardis mvn spring-boot:run Esecuzione da Eclipse (Undertow embedded) e console ..... Undertow started on port(s) 8080 (http) Started Application in 3.942 seconds (JVM running for 8.652) ..... Initializing Spring FrameworkServlet 'dispatcherServlet' FrameworkServlet 'dispatcherServlet': initialization started FrameworkServlet 'dispatcherServlet': initialization completed in 32 ms Implementazione → Embedding del container Eclipse: Run & Console
  • 14.
    ROME 27-28 march2015 - Luigi Bennardis <!-- JAVA PERSISTENCE API SUPPORT --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- H2 DATABASE --> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency> <spring-boot-starter-data-jpa> Configura la specifica JPA nel contesto di Spring <h2> Configura un datasource per l’istanza H2 eseguita in modalità embedded Maven: dichiarazione delle dipendenze Implementazione → H2 - Hibernate
  • 15.
    ROME 27-28 march2015 - Luigi Bennardis @Service public class ServicePrenotazioneEsame { private final IRepositoryPrenotazioneEsame prenEsameRepo; @Autowired public ServicePrenotazioneEsame( IRepositoryPrenotazioneEsame localRepo) { this.prenEsameRepo = localRepo; } public void registraPrenotazione(String codPrenotazione, String codEsame, String matricolaStud) { this.prenEsameRepo.save(new EntityPrenotazioneEsame(codPrenotazione, codEsame, matricolaStud)); } } @Service Business Service Facade che incapsula le funzioni di grana fine esponendo alla logica applicativa quelle a grana più grossa @Autowired Inietta la classe marcata nel contesto Spring Service Facade: metodo di registrazione della prenotazione Implementazione → H2 - Hibernate
  • 16.
    ROME 27-28 march2015 - Luigi Bennardis @RestController public class Controller { @Autowired private ApplicationContext context; @RequestMapping("/prenotaEsame") public String prenotaEsame(@RequestParam(value="matricola") String matricola,@RequestParam(value="esame") String esame) { ServicePrenotazioneEsame service = context.getBean(ServicePrenotazioneEsame.class); IRepositoryPrenotazioneEsame repository = context.getBean(IRepositoryPrenotazioneEsame.class); service.registraPrenotazione(codPrenotazione, esame, matricola); } @RequestMapping("/prenotazioniFatte") public String prenotazioniFatte() { IRepositoryPrenotazioneEsame repository = context.getBean(IRepositoryPrenotazioneEsame.class); return "PRENOTAZIONI PRESENTI IN BASE DATI: " + " <BR> " + repository.count() + " <BR> " + repository.findAll(); } } Controller: chiamata al metodo esposto dal Service Facade Implementazione → H2 - Hibernate
  • 17.
    ROME 27-28 march2015 - Luigi Bennardis @Component public class UnitTestCaricaTipologiche { private final IRepositoryEsame esameRepo; @Autowired public UnitTestCaricaTipologiche(IRepositoryEsame localRepo) { this.esameRepo = localRepo; } @PostConstruct // ANNOTAZIONE JSR 250 (SPECIFICA JAVA EE 5) ESEMPIO DI HOOK DEL CICLO DI VITA. public void inizializzaBaseDati() throws Exception { System.out.println("INIZIALIZZAZIONE TABELLA TIPOLOGICA ESAME"); this.esameRepo.save(new EntityEsame("00001", "Ingegneria Civile")); this.esameRepo.save(new EntityEsame("00002", "Ingegneria Elettronica")); this.esameRepo.save(new EntityEsame("00003", "Ingegneria Meccanica")); this.esameRepo.save(new EntityEsame("00004", "Ingegneria Informatica")); System.out.println("TABELLA TIPOLOGICA ESAME-> INIZIALIZZAZIONE COMPLETA RECORD: " + esameRepo.count()); } } @PostConstruct Marca il metodo ehe la classe esegue dopo essere stata istanziata H2 Emdedded -> JSR 250 LIFECICLE HOOKS Gestione dell’Inizializzazione del database (UT/IT) Implementazione → H2 - Hibernate
  • 18.
    ROME 27-28 march2015 - Luigi Bennardis ..... ..... Building JPA container EntityManagerFactory for persistence unit 'default' HHH000204: Processing PersistenceUnitInfo [ ..... ..... HHH000412: Hibernate Core {4.3.8.Final} HHH000206: hibernate.properties not found HHH000021: Bytecode provider name : javassist HCANN000001: Hibernate Commons Annotations {4.0.5.Final} HHH000400: Using dialect: org.hibernate.dialect.H2Dialect HHH000397: Using ASTQueryTranslatorFactory HHH000227: Running hbm2ddl schema export HHH000230: Schema export complete INIZIALIZZAZIONE TABELLA TIPOLOGICA ESAME TABELLA TIPOLOGICA ESAME-> INIZIALIZZAZIONE COMPLETA RECORD: 4..... ..... Esecuzione da Eclipse e console di output Implementazione → H2 - Hibernate mvn spring-boot:run Eclipse: Run & Console
  • 19.
    ROME 27-28 march2015 - Luigi Bennardis <!-- SPRING JMS --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> </dependency> <!-- HORNETQ --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-hornetq</artifactId> </dependency> <dependency> <groupId>org.hornetq</groupId> <artifactId>hornetq-jms-server</artifactId> </dependency> <!-- TOMEE EXTERNAL --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <!– PACKAGING J2EE--> <packaging>war</packaging> Maven: dichiarazione delle dipendenze e packaging J2EE Implementazione → HornetQ
  • 20.
    ROME 27-28 march2015 - Luigi Bennardis @SpringBootApplication public class Application extends SpringBootServletInitializer{ public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(Application.class); } } @SpringBootServletInitializer Inizializza il contesto Spring-Boot nel Container J2EE Esecuzione di Spring Boot nel servlet container J2EE Implementazione → HornetQ
  • 21.
    ROME 27-28 march2015 - Luigi Bennardis package it.luigibennardis.boot.demo.rest; import org.springframework.jms.annotation.JmsListener; import org.springframework.stereotype.Component; @Component public class CodaPrenotazioneEsame { @JmsListener(destination = "codaPrenotazioneEsami") public void onMessage(String content) { System.out.println("MESSAGGIO PUBBLICATO SULLA CODA codaPrenotazioneEsami :" + content); } } spring.hornetq.mode=embedded spring.hornetq.embedded.enabled=true spring.hornetq.embedded.queues=codaPrenotazioneEsami @Component Marca la classe per essere iniettata nel contesto di Spring in fase di scansione del classpath @JmsListener Marca il metodo che corrisponde al target del listener JMS Listener JMS: implementazione Implementazione → HornetQ HornetQ: direttive di configurazione
  • 22.
    ROME 27-28 march2015 - Luigi Bennardis @Service public class ServicePrenotazioneEsame { //..... @Autowired public ServicePrenotazioneEsame(IRepositoryPrenotazioneEsame localRepo,JmsTemplate jmsTemplate) { this.prenEsameRepo = localRepo; this.jmsTemplate = jmsTemplate; } public void registraPrenotazione(String codPrenotazione, String codEsame, String matricolaStud) { //PERSISTENZA DEI DATI SUL DATABASE this.prenEsameRepo.save(new EntityPrenotazioneEsame(codPrenotazione, codEsame, matricolaStud)); //PUBBLICAZIONE DEL MESSAGGIO SULLA CODA this.jmsTemplate.convertAndSend("codaPrenotazioneEsami", codPrenotazione + "|" + codEsame + "|" + matricolaStud); } } Service Facade: chiamata al metodo di scrittura del messaggio Implementazione → HornetQ
  • 23.
    ROME 27-28 march2015 - Luigi Bennardis mvn spring-boot: repackage java -jar targetdemo-spring-boot-h2embHibJmsJta-0.0.1-SNAPSHOT.war ..... HQ221000: live server is starting with configuration HornetQ Configuration (clustered=false,backup=false HQ221045: libaio is not available, switching the configuration into NIO HQ221043: Adding protocol support CORE HQ221003: trying to deploy queue jms.queue.codaPrenotazioneEsami HQ221007: Server is now live HQ221001: HornetQ Server version 2.4.5.FINAL (Wild Hornet, 124) [f9175388-bb5f-11e4-88d9- 5bae268d51f1] ..... ..... MESSAGGIO PUBBLICATO SULLA CODA codaPrenotazioneEsami :PRE00001|abcd0001|000001 MESSAGGIO PUBBLICATO SULLA CODA codaPrenotazioneEsami :PRE00001|abcd0003|000001 MESSAGGIO PUBBLICATO SULLA CODA codaPrenotazioneEsami :PRE00001|abcd0005|000001 ..... Distribuzione su TOMEE e console di output Implementazione → HornetQ Command Line: Run & Console
  • 24.
    ROME 27-28 march2015 - Luigi Bennardis <!-- TRANSAZIONALITA' ATOMIKOS --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jta-atomikos</artifactId> </dependency> <spring-boot-starter-jta-atomikos> Definisce la dipendenza alle librerie di Atomikos e auto- configura il container di esecuzione con le funzioni di transazionalità Maven: dichiarazione delle dipendenze Implementazione → H2 - Atomikos
  • 25.
    ROME 27-28 march2015 - Luigi Bennardis @Service @Transactional public class ServicePrenotazioneEsame { //…… public void registraPrenotazione(String codPrenotazione, String codEsame, String matricolaStud) { //PERSISTENZA DEL RECORD SUL DATABASE this.prenEsameRepo.save(new EntityPrenotazioneEsame(codPrenotazione, codEsame, matricolaStud)); //PUBBLICAZIONE DEL MESSAGGIO SULLA CODA this.jmsTemplate.convertAndSend("codaPrenotazioneEsami", codPrenotazione + "|" + codEsame + "|" + matricolaStud); if (codEsame.equals("ROLLBACK_SIMULATO")) { //ECCEZIONE->ROLLBACK TRANSAZIONE throw new RuntimeException("SIMULAZIONE DI ROLLBACK ULTIMA TRANSAZIONE"); } } @Transactional • Marca in modo dichiarativo i confini della transazionalità • Eccezione fake per eseguire il rollback Service facade: codifica della direttiva JTA Implementazione → Atomikos
  • 26.
    ROME 27-28 march2015 - Luigi Bennardis mvn spring-boot:repackage java -jar target/demo-spring-boot-h2embHibJmsJta-0.0.1-SNAPSHOT.war Esecuzione da command line e console Implementazione → Atomikos Command Line: Run & Console ..... ..... No properties path set - looking for transactions.properties in classpath... transactions.properties not found - looking for jta.properties in classpath... Failed to open transactions properties file - using default values Using JTA UserTransaction: com.atomikos.icatch.jta.UserTransactionManager@bb479 Using JTA TransactionManager: com.atomikos.icatch.jta.UserTransactionManager@bb479 ..... ..... MESSAGGIO PUBBLICATO SULLA CODA codaPrenotazioneEsami :PROGRESSIVO MESSAGGIO IN CODA 1|PRE00001|abcd0001|000001 MESSAGGIO PUBBLICATO SULLA CODA codaPrenotazioneEsami :PROGRESSIVO MESSAGGIO IN CODA 2|PRE00001|abcd0002|000001 SIMULAZIONE DI ROLLBACK ULTIMA TRANSAZIONE
  • 27.
    ROME 27-28 march2015 - Luigi Bennardis <plugin> <groupId>org.cloudfoundry</groupId> <artifactId>cf-maven-plugin</artifactId> <version>1.0.1</version> <configuration> <server>pivotal-cloud-foundry</server> <target>https://api.run.pivotal.io</target> <org>luigibennardis.it</org> <space>development</space> <appname>demoSpringBoot</appname> <url>demoSpringBoot.cfapps.io</url> <memory>1024</memory> </configuration> </plugin> Maven: plug-in deploy Cloud Foundry Implementazione → Cloud Foundry
  • 28.
    ROME 27-28 march2015 - Luigi Bennardis cf:push -Dcf.username=l.bennardis@email.it -Dcf.password=password ..... [INFO] Creating application 'demoSpringBoot' [INFO] Uploading 'C:developmentEclipseWKS05-demo-spring-boot- h2embHibJmsTransactionalCFtargetdemo-spring-boot-h2embHibJmsJtaCf-0.0.1-SNAPSHOT.war' [INFO] Starting application [INFO] -----> Downloaded app package (29M) -----> Java Buildpack Version: v2.7.1 | https://github.com/cloudfoundry/java-buildpack#fee275a -----> Downloading Open Jdk JRE 1.8.0_40 from https://download.run.pivotal.io/openjdk/lucid/x86_64/openjdk-1.8.0_40.tar.gz (2.6s) Expanding Open Jdk JRE to .java-buildpack/open_jdk_jre (1.3s) -----> -----> Downloading Spring Auto Reconfiguration 1.7.0_RELEASE from https://download.run.pivotal.io/auto-reconfiguration/auto-reconfiguration-1.7.0_RELEASE.jar (0.1s) -----> Uploading droplet (73M) [INFO] Checking status of application 'demoSpringBoot' [INFO] 0 of 1 instances running (1 starting) [INFO] ..... [INFO] 1 of 1 instances running (1 running) Maven: deploy & console Implementazione → Cloud Foundry
  • 29.
    ROME 27-28 march2015 - Luigi Bennardis Gestione dell’istanza Implementazione → Cloud Foundry Cloud Foundry: Tail Log - Scale up & Console
  • 30.
    ROME 27-28 march2015 - Luigi Bennardis Implementazione → Cloud Foundry Gestione dell’istanza con il Plug-in di Eclipse
  • 31.
    ROME 27-28 march2015 - Luigi Bennardis Gestione dell’istanza con il Plug-in di Eclipse Implementazione → Cloud Foundry
  • 32.
    ROME 27-28 march2015 - Luigi Bennardis Conclusioni  Rapido sviluppo di applicazioni basate su Spring  Vista semplificata dell’ecosistema Spring e delle dipendenze  Auto-configurazione dell’applicazione in base alle librerie dichiarate nel classpath:  H2->datasource+embedding  Hibernate->JPA provider  Progressivo «scale-up» dei componenti «auto-configurati» con versioni più robuste  Soddisfazione di requisiti non funzionali comuni a molti progetti  Copertura di una significativa area del ciclo di vita  Costi ridotti in fase di start-up  Nessuna gestione degli ambienti di run-time (SO/Mware)  Nessuna configurazione server side  Nessun «middleware» installato o da gestire  Flessibilità ed efficienza del deployment  Software design che abilita al Cloud (PAAS)  Altri: Sicurezza, metriche, esternalizzazione di configurazioni
  • 33.
    ROME 27-28 march2015 - Luigi Bennardis Appendice: JAX-RS (JERSEY) & JSR 330  Soluzione presentata: Spring-Boot -> RESTFull Web Service basato su Spring:  stack completo comprendente MVC, REST, ecc.  annotazioni potenti (Dependency & Context Injection) ma proprietarie Spring.  Evoluzione della soluzione: Spring-Boot -> RESTFull Web Service basato su Jersey & JSR-330  Jersey: framework OS per realizzare Web Services RESTful attraverso API Java JAX-RS  JSR-330: specifica Java per il Contexts and Dependency Injection le piattaforme Java EE.  Iniezione di un Java Bean: @Autowired (Spring) -> @Inject (JSR-330)  Dichiarazione di un Java Bean: @Component(Spring) -> @Named(JSR-330)
  • 34.
    ROME 27-28 march2015 - Luigi Bennardis @SpringBootApplication public class Application { @Named public static class JerseyConfig extends ResourceConfig { public JerseyConfig() { this.register(Controller.class); } } public static void main(String[] args) { SpringApplication.run(Application.class, args); } } @Named Dichiarazione di iniezione di un Java Bean nel contesto in fase di scansione del classpath Classe Java per eseguire Spring-Boot con Jersey Implementazione JAX-RS: JERSEY- JSR330
  • 35.
    ROME 27-28 march2015 - Luigi Bennardis @Named @Transactional public class ServicePrenotazioneEsame { @Inject private JmsTemplate jmsTemplate; @PersistenceContext private EntityManager entityManager; public void registraPrenotazione(String codPrenotazione, String codEsame, String matricolaStud) { //PERSISTENZA DATI SUL DATABASE this.entityManager.persist(new EntityPrenotazioneEsame(codPrenotazione, codEsame, matricolaStud)); //PUBBLICAZIONE MESSAGGIO SULA CODA this.jmsTemplate.convertAndSend("codaPrenotazioneEsami","PROGRESSIVO MESSAGGIO IN CODA "+ counter.incrementAndGet( )+ "|" + codPrenotazione + "|" + codEsame + "|" + matricolaStud); @Inject Punto di iniezione di un Java Bean: non sono necessari set/get Service Facade: annotazioni JSR-330 Implementazione JAX-RS: JERSEY- JSR330
  • 36.
    ROME 27-28 march2015 - Luigi Bennardis @Named @Path("/prenotaEsameTest") @Produces(MediaType.TEXT_HTML) public class Controller { @Inject private ServicePrenotazioneEsame service; @GET @Path("/infoPrenota") public Response get(@QueryParam("codiceEsame") String codiceEsame, @QueryParam("matricolaStudente") String matricolaStudente) { //………… try { service.registraPrenotazione("aa00099",codiceEsame, matricolaStudente); esitoPrenotazione = "ESEGUITA"; } //………… } @GET Metodo Get della request HTTP @Path Definisce la corrispondenza della risorsa (sub-risorsa) alla classe (metodo) Controller REST: annotazioni Jersey Implementazione JAX-RS: JERSEY- JSR330
  • 37.
    ROME 27-28 march2015 - Luigi Bennardis Link  https://github.com/lbennardis/Codemotion15SpringBoot (codice sorgente)  http://projects.spring.io/spring-boot/ (Spring-Boot)  http://tomee.apache.org/ (Tomcat EE)  http://cloudfoundry.org/index.html (Cloud Foundry)  https://jersey.java.net/ (Jersey)  https://jcp.org/en/jsr/detail?id=330 (JSR-330)  https://jcp.org/en/jsr/detail?id=250 (JSR-250)
  • 38.
    ROME 27-28 march2015 - Luigi Bennardis Leave your feedback on Joind.in! https://joind.in/event/view/3347