Cette page montre comment écrire un premier bean @ApplicationScoped, le câbler via @Inject, et démarrer le container. La compilation génère tout le bytecode d’injection : aucun proxy dynamique, aucune réflexion au runtime.
Pré-requis
-
Java 25 — Temurin recommandé. Module path activé.
-
Maven 3.9.16 — épinglé via
.sdkmanrcà la racine du repo. -
JPMS strict : un
module-info.javapar module Maven.
Coordonnées Maven
<dependencies>
<dependency>
<groupId>io.vidocq.vauban</groupId>
<artifactId>vauban-api</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.vidocq.vauban</groupId>
<artifactId>vauban-core</artifactId>
<version>0.1.0-SNAPSHOT</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.vidocq.vauban</groupId>
<artifactId>vauban-processor</artifactId>
<version>0.1.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.vidocq.vauban</groupId>
<artifactId>vauban-maven-plugin</artifactId>
<version>0.1.0-SNAPSHOT</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Premier bean @ApplicationScoped
package io.example;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class GreetingService {
public String hello(String name) {
return "Hello, " + name + "!";
}
}
Premier @Inject
package io.example;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
@ApplicationScoped
public class HelloApp {
@Inject GreetingService greeting;
public void run() {
System.out.println(greeting.hello("Vauban"));
}
}
|
L’injection par champ et l’injection par constructeur sont supportées. L’injection par constructeur est recommandée pour faciliter les tests unitaires hors container. |
module-info.java minimal
module io.example {
requires jakarta.cdi;
requires io.vidocq.vauban.api;
exports io.example;
}
Bootstrap du container
import io.vidocq.vauban.api.Vauban;
void main() {
try (var container = Vauban.bootstrap()) {
var app = container.select(HelloApp.class).get();
app.run();
}
}
try-with-resources ferme proprement le container : les @PreDestroy sont appelés, les contextes purgés, les événements @BeforeDestroyed(ApplicationScoped.class) puis @Destroyed(ApplicationScoped.class) sont émis.
Build et exécution
sdk env
./mvnw -ntp install -DskipTests
java --module-path target/modules --module io.example/io.example.Main
Le plugin Maven a généré dans target/generated-sources/ les _Factory correspondant à chaque bean. Aucune réflexion ne tournera au démarrage : Vauban se contente d’instancier ces factories puis d’appeler les méthodes générées.
Trois modes de découverte des beans
Vauban supporte trois stratégies, selon le contexte :
| Mode | Usage | API |
|---|---|---|
|
Application standard mono-module |
|
|
Application multi-modules avec dépendances CDI transitives |
|
|
Tests unitaires, sélection programmatique |
|
Étape suivante
-
Cas d’usage avancés — qualifiers, producers, événements, intercepteurs.
-
Concepts — bean, scope, qualifier, BeanManager.