Ein Spring-Boot-Projekt folgt einer klaren Struktur. Diese Struktur ist kein Zufall – sie ist Teil der Konventionen. Wer sich daran hält, profitiert von Auto-Konfiguration und vermeidet Reibungsverluste.
Das Arcade-Projekt zeigt den typischen Aufbau:
arcade-highscore-api/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── de/digitalfrontiers/arcade/
│ │ │ ├── ArcadeHighscoreApplication.java
│ │ │ ├── domain/
│ │ │ │ ├── Player.java
│ │ │ │ ├── Game.java
│ │ │ │ └── Score.java
│ │ │ └── web/
│ │ │ └── HomeController.java
│ │ └── resources/
│ │ ├── application.yaml
│ │ ├── static/
│ │ │ └── css/
│ │ │ └── arcade.css
│ │ └── templates/
│ │ └── index.html
│ └── test/
│ └── java/
│ └── de/digitalfrontiers/arcade/
│ └── ArcadeHighscoreApplicationTests.java
├── build.gradle.kts
├── settings.gradle.kts
└── gradlew
Diese Struktur ist kein Spring-Boot-Spezifikum. Sie folgt dem Maven-Standard-Layout, das sich in der Java-Welt durchgesetzt hat. Gradle übernimmt es, Spring Boot baut darauf auf.
src/main/java enthält den Produktionscode. Hier liegen deine Klassen, gruppiert in Packages.
src/main/resources enthält alles, was keine Java-Klasse ist: Konfigurationsdateien, Templates, statische Assets. Spring Boot scannt dieses Verzeichnis und macht den Inhalt verfügbar.
src/test/java enthält Testklassen. Die Paketstruktur
spiegelt den Produktionscode – Tests für
de.digitalfrontiers.arcade.domain.Player liegen in
de.digitalfrontiers.arcade.domain.PlayerTest.
Die Hauptklasse ArcadeHighscoreApplication liegt im
Root-Package de.digitalfrontiers.arcade. Das ist wichtig.
Spring Boot scannt ab diesem Package abwärts nach Komponenten.
Übliche Sub-Packages und ihre Zwecke:
| Package | Inhalt | Beispiel |
|---|---|---|
domain |
Fachliche Entitäten | Player, Game, Score |
web oder controller |
HTTP-Endpoints | HomeController, ScoreController |
service |
Geschäftslogik | HighscoreService |
repository |
Datenbankzugriff | PlayerRepository |
config |
Konfigurationsklassen | WebConfig, SecurityConfig |
Diese Aufteilung ist Konvention, keine Pflicht. Du könntest alles in ein Package werfen – aber niemand würde es dir danken.
Namen sind wichtig. Sie kommunizieren Absicht.
Diese Suffixe sind mehr als Dekoration. Spring Boot und IDEs nutzen
sie für Autovervollständigung, Navigation und Analyse. Ein
PlayerController wird in der IDE als Controller erkannt und
entsprechend behandelt.
Für Entitäten wie Player, Game,
Score gibt es kein Suffix. Sie sind, was sie sind –
fachliche Konzepte ohne technische Rolle.
Die build.gradle.kts des Arcade-Projekts referenziert
“Starters”:
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
}Ein Starter ist ein Dependency-Bündel. Statt zehn einzelne Bibliotheken aufzulisten, fügst du einen Starter hinzu – er bringt alles Nötige mit.
Die wichtigsten Starters für den Einstieg:
| Starter | Zweck |
|---|---|
spring-boot-starter |
Basis (Logging, YAML, Auto-Config) |
spring-boot-starter-web |
REST APIs, Webanwendungen |
spring-boot-starter-thymeleaf |
Server-Side Rendering |
spring-boot-starter-data-jpa |
Relationale Datenbanken |
spring-boot-starter-data-mongodb |
MongoDB |
spring-boot-starter-test |
JUnit 5, Mockito, AssertJ |
spring-boot-starter-actuator |
Monitoring-Endpoints |
Starters folgen einem Namensschema:
spring-boot-starter-*. Wenn du nicht sicher bist, welche
Abhängigkeiten du brauchst, such nach dem passenden Starter.
Der resources-Ordner hat besondere Bedeutung. Spring
Boot behandelt bestimmte Unterverzeichnisse und Dateien speziell.
application.yaml (oder .properties) ist
die zentrale Konfigurationsdatei. Spring Boot lädt sie automatisch beim
Start.
static/ enthält statische Ressourcen – CSS,
JavaScript, Bilder. Der Inhalt ist unter der Root-URL verfügbar:
/static/css/arcade.css wird zu
/css/arcade.css.
templates/ enthält Server-Side-Templates für Thymeleaf, FreeMarker oder andere Template-Engines.
Jedes Spring-Boot-Projekt hat genau eine Klasse mit
@SpringBootApplication:
@SpringBootApplication
public class ArcadeHighscoreApplication {
public static void main(String[] args) {
SpringApplication.run(ArcadeHighscoreApplication.class, args);
}
}Diese Klasse ist der Einstiegspunkt. Die main-Methode
startet Spring Boot. Die Annotation @SpringBootApplication
ist eine Kombination aus drei Annotationen:
Deshalb ist die Position dieser Klasse wichtig.
@ComponentScan scannt ab dem Package der annotierten
Klasse. Liegt ArcadeHighscoreApplication in
de.digitalfrontiers.arcade, werden alle Klassen in diesem
Package und darunter gefunden.
Eine Klasse in com.example.other würde nicht gefunden.
Sie liegt außerhalb des Scan-Bereichs.