Frameworks Java¶
L'écosystème Java propose plusieurs frameworks de premier plan pour le développement d'applications web et de microservices. Spring Boot domine les deployements entreprise, tandis que Quarkus et Micronaut répondent aux contraintes des architectures cloud-native. Cette section présente les options majeures avec des exemples concrets.
Comparatif des frameworks principaux¶
| Framework | Modèle | Démarrage | Mémoire | GraalVM natif | Idéal pour |
|---|---|---|---|---|---|
| Spring Boot | Full-stack | ~2-5s | ~200 MB | Partiel | Applications enterprise, équipes larges |
| Quarkus | Cloud-native | ~0.05s | ~50 MB | Excellent | Microservices, serverless, Kubernetes |
| Micronaut | Cloud-native | ~0.1s | ~70 MB | Excellent | Microservices, IoT, applications GraalVM |
| Jakarta EE | Standard JEE | ~5-10s | ~300 MB | Limite | Applications JEE legacy, serveurs app |
| Helidon | MicroProfile | ~0.5s | ~80 MB | Oui | Microservices Oracle Cloud, MicroProfile |
Spring Boot¶
Spring Boot est le framework Java le plus repandu en entreprise. Il s'appuie sur le Spring Framework et applique le principe de convention over configuration : une application fonctionnelle nécessité un minimum de configuration explicite.
Contrôleur REST minimal¶
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.*;
import java.util.List;
// Point d'entree de l'application
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
// Controleur REST simple
@RestController
@RequestMapping("/api/messages")
public class MessageController {
// GET /api/messages — retourne une liste JSON
@GetMapping
public List<String> lister() {
return List.of("Bonjour", "Hello", "Hola");
}
// POST /api/messages — recoit un corps JSON
@PostMapping
public String creer(@RequestBody String message) {
return "Recu : " + message;
}
}
Spring Initializr
Generez un projet Spring Boot en quelques secondes sur start.spring.io. Selectionnez les dépendances (Web, JPA, Validation, etc.) et telechargez une archive Maven ou Gradle prete à l'emploi.
Quand utiliser Spring Boot¶
- Équipe déjà formee Spring / Spring Boot
- Applications enterprise avec sécurité complexe (Spring Security)
- Besoin d'un écosystème très large (Spring Data, Spring Batch, Spring Intégration)
- Integrations cloud (Spring Cloud, Spring Cloud Gateway)
Quarkus¶
Quarkus est développé par Red Hat et optimise pour Kubernetes et GraalVM. Son point fort est le temps de démarrage ultra-rapide et la faible empreinte mémoire, rendus possibles par un traitement des annotations à la compilation plutôt qu'au runtime.
Contrôleur REST avec Quarkus¶
package com.example;
import jakarta.inject.Inject;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import java.util.List;
// Quarkus utilise JAX-RS pour les endpoints REST
@Path("/api/produits")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class ProduitResource {
@Inject
ProduitService service;
// GET /api/produits
@GET
public List<Produit> lister() {
return service.listerTous();
}
// GET /api/produits/{id}
@GET
@Path("/{id}")
public Response trouver(@PathParam("id") Long id) {
return service.trouverParId(id)
.map(p -> Response.ok(p).build())
.orElse(Response.status(Response.Status.NOT_FOUND).build());
}
// POST /api/produits
@POST
public Response creer(Produit produit) {
Produit cree = service.creer(produit);
return Response.status(Response.Status.CREATED).entity(cree).build();
}
}
# Mode developpement avec hot reload
./mvnw quarkus:dev
# Compilation native GraalVM
./mvnw package -Pnative
# Image Docker native
./mvnw package -Pnative -Dquarkus.native.container-build=true
Quand utiliser Quarkus¶
- Déploiements Kubernetes avec contraintes mémoire strictes
- Fonctions serverless (AWS Lambda, Azure Functions)
- Microservices a démarrage rapide pour le scaling horizontal
- Équipes souhaitant rester proches des standards Jakarta EE
Micronaut¶
Micronaut adopte une approche similaire à Quarkus : injection de dépendances et AOP resolus à la compilation via un processeur d'annotations (APT), ce qui élimine la réflexion au runtime et accéléré le démarrage.
Contrôleur REST avec Micronaut¶
package com.example;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.annotation.*;
import java.util.List;
// @Controller definit le prefixe de chemin
@Controller("/api/articles")
public class ArticleController {
private final ArticleService service;
// Injection par constructeur (recommande)
public ArticleController(ArticleService service) {
this.service = service;
}
// GET /api/articles
@Get
public List<Article> lister() {
return service.listerTous();
}
// GET /api/articles/{id}
@Get("/{id}")
public HttpResponse<Article> trouver(Long id) {
return service.trouverParId(id)
.map(HttpResponse::ok)
.orElse(HttpResponse.notFound());
}
// DELETE /api/articles/{id}
@Delete("/{id}")
public HttpResponse<Void> supprimer(Long id) {
service.supprimer(id);
return HttpResponse.noContent();
}
}
Quand utiliser Micronaut¶
- Applications GraalVM native sans configuration supplémentaire
- Microservices avec tests rapides (pas de réflexion = démarrage context de test en ms)
- Projets multi-langages JVM (Kotlin, Groovy supportes nativement)
Jakarta EE¶
Jakarta EE (anciennement Java EE) est le standard enterprise Java géré par Eclipse Foundation depuis 2017. Il définit un ensemble de spécifications (Servlets, JPA, CDI, JAX-RS, JMS, etc.) implementees par des serveurs d'applications.
package com.example;
import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import jakarta.persistence.*;
// CDI bean a portee requete
@RequestScoped
@Path("/commandes")
@Produces(MediaType.APPLICATION_JSON)
public class CommandeResource {
@Inject
private EntityManager em; // JPA EntityManager injecte par le conteneur
@GET
public List<Commande> lister() {
return em.createQuery("SELECT c FROM Commande c", Commande.class)
.getResultList();
}
}
Serveurs d'applications Jakarta EE courants : WildFly, Payara, Open Liberty, GlassFish.
Écosystème complementaire¶
Au-delà des frameworks web, plusieurs bibliotheques sont incontournables dans les projets Java :
Hibernate / Spring Data JPA¶
ORM de référence pour la persistance relationnelle.
import jakarta.persistence.*;
// Entite JPA — mappee sur la table "utilisateurs"
@Entity
@Table(name = "utilisateurs")
public class Utilisateur {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, length = 100)
private String nom;
@Column(unique = true, nullable = false)
private String email;
}
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
// Repository Spring Data — pas d'implementation a ecrire
public interface UtilisateurRepository extends JpaRepository<Utilisateur, Long> {
// Requete derivee du nom de methode
Optional<Utilisateur> findByEmail(String email);
// JPQL explicite
@Query("SELECT u FROM Utilisateur u WHERE u.nom LIKE %:terme%")
List<Utilisateur> rechercherParNom(String terme);
}
Lombok¶
Lombok réduit le boilerplate Java via des annotations traitees à la compilation.
import lombok.*;
// Genere : getters, setters, equals, hashCode, toString, constructeur tous args
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProduitDto {
private Long id;
private String nom;
private Double prix;
}
// Utilisation du builder genere par Lombok
ProduitDto dto = ProduitDto.builder()
.id(1L)
.nom("Clavier")
.prix(89.99)
.build();
Lombok et Java modernes
Avec Java 16+, les records remplacent avantageusement Lombok pour les objets de valeur immuables. Preferez les records pour les DTO et les classes de configuration. Reservez Lombok aux entités mutables (JPA) ou aux cas où la mutabilite est nécessaire.
MapStruct¶
MapStruct généré du code de mapping entre objets (entités \<-> DTO) à la compilation.
import org.mapstruct.*;
@Mapper(componentModel = "spring") // Genere un bean Spring
public interface UtilisateurMapper {
// Mapping direct si les noms de champs correspondent
UtilisateurDto toDto(Utilisateur utilisateur);
// Mapping inverse avec exclusion d'un champ
@Mapping(target = "motDePasse", ignore = true)
Utilisateur toEntity(UtilisateurDto dto);
// Mapping de liste
List<UtilisateurDto> toDtoList(List<Utilisateur> utilisateurs);
}
Spring Security¶
Framework d'authentification et d'autorisation pour les applications Spring.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/public/**").permitAll()
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> {}))
.build();
}
}