Quarkus met les annotations au cœur de l'expérience développeur.
Construit sur les standards Java (CDI, JAX-RS, MicroProfile), il permet de déclarer le comportement d'une application avec un minimum de configuration explicite.
Pourquoi utiliser les annotations dans Quarkus ?
Les annotations permettent de rendre le code :
- Plus déclaratif : on exprime l'intention plutôt que d'empiler de la configuration.
- Plus lisible : on localise les règles au plus près du code concerné.
- Moins couplé : l'injection de dépendances et les contrats restent clairs.
- Plus productif : la plupart des intégrations Quarkus se configurent en quelques annotations.
Passons aux familles d'annotations les plus utiles.
Annotations de configuration et de cycle de vie
@QuarkusMain
@QuarkusMain permet de personnaliser l'entrée de l'application en fournissant sa propre classe main, tout en laissant Quarkus gérer le démarrage.
Utile quand on veut contrôler finement le bootstrap ou brancher un mode d'exécution spécifique (batch, CLI, etc.).
@QuarkusMain
public class DemoApplication implements QuarkusApplication {
@Override
public int run(String... args) {
// point d'entrée custom
return 0;
}
}
@ConfigProperty
@ConfigProperty injecte une valeur de configuration depuis application.properties ou l'environnement.
C'est l'équivalent simple d'un "champ de configuration typé", sans avoir à créer une classe de configuration dédiée.
@ApplicationScoped
public class MailerConfig {
@ConfigProperty(name = "mailer.host")
String host;
}
@Startup
@Startup force l'initialisation d'un bean au démarrage (utile pour précharger un cache, vérifier une connexion, etc.).
Le hook d'initialisation réel se fait généralement via @PostConstruct.
@Startup
@ApplicationScoped
public class WarmupService {
@PostConstruct
void init() {
// warmup
}
}
Annotations de définition de composants (CDI)
Quarkus utilise CDI (Contexts and Dependency Injection) pour gérer les beans.
@ApplicationScoped
Scope singleton au niveau de l'application.
Le bean est créé une seule fois et réutilisé partout, idéal pour la logique métier sans état (stateless).
@ApplicationScoped
public class UserService {
public User getUserById(Long id) {
return null;
}
}
@RequestScoped
Un bean par requête HTTP.
Pratique pour stocker un contexte lié à la requête (identifiant, métadonnées, etc.), sans le propager manuellement.
@RequestScoped
public class RequestContext {
public String requestId() {
return "req-1";
}
}
@Singleton et @Dependent
@Singleton force une instance unique, @Dependent crée une instance par injection.
Attention : @Singleton peut poser problème si l'on stocke un l'état mutable partagé.
À l'inverse, @Dependent peut multiplier les instances et impacter la mémoire si on l'injecte partout.
@Singleton
public class CacheService {}
@Dependent
public class Helper {}
@Inject
@Inject permet d’injecter une dépendance gérée par CDI dans une classe.
Injection par champ
@ApplicationScoped
public class UserResource {
@Inject
UserService userService;
}
Cette approche est concise, mais elle présente quelques limites :
- Les dépendances sont moins visibles
- Les tests unitaires sont plus difficiles à mettre en place
Injection par constructeur
@ApplicationScoped
public class UserResource {
private final UserService userService;
@Inject
public UserResource(UserService userService) {
this.userService = userService;
}
}
Cette approche est généralement préférable :
- Les dépendances sont explicites
- Les champs peuvent être
final - La classe est plus facile à tester
Injection implicite
Avec Quarkus (et CDI), si une classe ne possède qu’un seul constructeur, l’annotation @Inject peut être omise :
@ApplicationScoped
public class UserResource {
private final UserService userService;
public UserResource(UserService userService) {
this.userService = userService;
}
}
Le framework détecte automatiquement le constructeur à utiliser.
Annotations REST (JAX-RS)
Quarkus s'appuie sur JAX-RS pour définir des endpoints REST.
@Path, @GET, @POST, @PUT, @DELETE
@Path définit le chemin racine d'une ressource ou d'une méthode.
Les annotations HTTP (@GET, @POST, @PUT, @DELETE) déclarent l'intention et mappent la méthode Java à l'action HTTP.
On peut aussi préciser les formats attendus avec @Produces (sortie) et @Consumes (entrée), ce qui clarifie le contrat API.
@Path("/users")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class UserResource {
@GET
public List<User> list() {
return List.of();
}
@GET
@Path("/{id}")
public User get(@PathParam("id") Long id) {
return null;
}
@POST
public User create(User user) {
return user;
}
}
@PathParam, @QueryParam, @HeaderParam, @BeanParam
Ces annotations extraient des données de la requête :@PathParam pour un segment d'URL, @QueryParam pour un paramètre de requête, @HeaderParam pour un en-tête.@BeanParam permet de regrouper plusieurs paramètres dans un objet dédié, pratique pour factoriser.
@GET
@Path("/{id}")
public User get(
@PathParam("id") Long id,
@QueryParam("details") boolean details,
@HeaderParam("X-Request-Id") String requestId
) {
return null;
}
@RestClient et @RegisterRestClient
Pour déclarer un client HTTP typé.
Idéal pour isoler les appels externes dans une interface claire, avec une configuration dédiée par configKey.
@RegisterRestClient(configKey = "users-api")
public interface UsersClient {
@GET
@Path("/users")
List<User> list();
}
@ApplicationScoped
public class UsersGateway {
@Inject
@RestClient
UsersClient client;
}
Annotations de transactions et de persistance
@Transactional
Délimite une transaction.
Pratique pour encapsuler une unité de travail métier sans gérer manuellement le commit/rollback.
@ApplicationScoped
public class UserService {
@Transactional
public User create(User user) {
return user;
}
}
Annotations de sécurité
Quarkus s'appuie sur les annotations standards Java EE / Jakarta.
Le mode d'authentification se configure via application.properties (par exemple Basic, JWT, OIDC), puis les annotations cadrent l'accès.
@RolesAllowed, @Authenticated et @PermitAll
@Authenticated exige un utilisateur authentifié, tandis que @RolesAllowed ajoute une contrainte de rôle.@PermitAll autorise l'accès à tout le monde, y compris sans authentification.
@Path("/admin")
public class AdminResource {
@GET
@RolesAllowed("admin")
public String panel() {
return "ok";
}
}
Annotations d'événements (CDI)
@Observes
@Observes permet de réagir à des événements CDI sans coupler les producteurs et les consommateurs.
Utile pour découpler des actions transversales (audit, notifications, métriques).
@ApplicationScoped
public class AuditService {
void onUserCreated(@Observes UserCreatedEvent event) {
// log
}
}
Annotations de tests
@QuarkusTest
Charge le contexte Quarkus complet pour les tests d'intégration.
On peut y injecter des beans CDI comme en production et tester le comportement réel.
@QuarkusTest
public class UserResourceTest {
@Test
void list_should_return_users() {
// test
}
}
@QuarkusIntegrationTest
Exécute les tests contre l'application packagée.
@QuarkusIntegrationTest
public class UserResourceIT extends UserResourceTest {}
@InjectMock
Pour mocker un bean CDI pendant un test.
Le mock remplace le bean réel dans le contexte, ce qui simplifie l'isolation des dépendances.
@QuarkusTest
public class UserServiceTest {
@InjectMock
UserRepository userRepository;
}
Conclusion
Comme Spring Boot, Quarkus mise sur les annotations pour réduire la configuration et rendre le code expressif.
Les annotations CDI structurent les composants, JAX-RS expose les endpoints, et MicroProfile fournit la configuration.
C'est un socle solide pour construire des services Java modernes, rapides et maintenables.
La version pour Spring Boot est juste ici :

Les annotations dans Spring Boot
