Ich habe Java nicht durch Bücher oder Online-Kurse gelernt. Ich habe es mir angeeignet, indem ich an einem echten Open-Source-Projekt gearbeitet habe: Alf.io, einem Ticketing-System für Events. Diese Erfahrung war intensiv, frustrierend und am Ende unglaublich lehrreich.
In dieser zweiteiligen Artikel-Serie teile ich, was ich dabei über Spring Boot gelernt habe. In Teil 1 geht es um die Grundlagen. In Teil 2 zeige ich dir, wie du Alf.io auf deinem eigenen Server installierst - inklusive der Probleme, die ich dabei hatte.
Warum Spring Boot 2025 noch relevant ist
Spring Boot dominiert die Java-Backend-Entwicklung. Laut Stack Overflow Developer Survey nutzen über 60% der Java-Entwickler Spring. Und das aus gutem Grund:
- Schneller Einstieg - In Minuten ein lauffähiges Projekt
- Produktionsreif - Embedded Server, Health Checks, Metrics
- Riesiges Ökosystem - Security, Data, Cloud - alles integriert
- Aktive Community - Viele Ressourcen, schnelle Hilfe
Auch wenn Node.js und Go populärer werden: Für Enterprise-Anwendungen, Finanzsektor und komplexe Business-Logik bleibt Java mit Spring Boot erste Wahl.
Was ist Alf.io?
Alf.io ist ein Open-Source Ticketing-System für Konferenzen, Meetups und Workshops. Es unterstützt Zahlungen über Stripe, PayPal und Banküberweisungen, bietet Check-in-Apps und ist DSGVO-konform.
Technisch ist Alf.io ein perfektes Lernprojekt:
- Spring Boot als Framework
- PostgreSQL als Datenbank
- Gradle als Build-System
- Mustache für Templates
- Eine saubere, gut dokumentierte Codebase
Wenn du echten Produktionscode lesen willst, schau dir das GitHub Repository an.
Was ist Spring Boot?
Spring Boot ist eine Erweiterung des Spring Frameworks, die den Einstieg drastisch vereinfacht. Das klassische Spring erforderte viel XML-Konfiguration. Spring Boot folgt dem Prinzip "Convention over Configuration" - vernünftige Standardwerte, die du bei Bedarf überschreiben kannst.
Spring Framework vs. Spring Boot
| Spring Framework | Spring Boot |
|---|---|
| Manuelles Setup von Servlet Container | Embedded Tomcat/Jetty |
| XML oder Java Config für alles | Auto-Configuration |
| Dependencies manuell verwalten | Starter Dependencies |
| Viel Boilerplate-Code | Minimaler Code zum Start |
Die Magie der Starter Dependencies
Statt dutzende Dependencies einzeln hinzuzufügen, nutzt du "Starter":
<!-- Eine Dependency für Web-Entwicklung -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Dieser eine Starter bringt mit: Spring MVC, Tomcat, Jackson (JSON), Validation - alles in kompatiblen Versionen.
Das erste Spring Boot Projekt
Der schnellste Weg: Spring Initializr.
- Wähle Maven oder Gradle
- Java Version (17 oder 21 empfohlen)
- Dependencies: "Spring Web" für REST APIs
- Generate und entpacken
Die Projektstruktur sieht so aus:
my-app/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/example/myapp/
│ │ │ └── MyAppApplication.java
│ │ └── resources/
│ │ └── application.properties
│ └── test/
├── pom.xml (oder build.gradle)
└── mvnw / gradlew
Die Hauptklasse
package com.example.myapp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyAppApplication {
public static void main(String[] args) {
SpringApplication.run(MyAppApplication.class, args);
}
}
Die @SpringBootApplication Annotation ist ein Shortcut für:
@Configuration- Diese Klasse definiert Beans@EnableAutoConfiguration- Auto-Konfiguration aktivieren@ComponentScan- Nach Komponenten in diesem Package suchen
Starte die App mit ./mvnw spring-boot:run und öffne http://localhost:8080.
Dependency Injection verstehen
Das Herzstück von Spring ist Dependency Injection (DI). Statt Objekte selbst zu erstellen, "injiziert" Spring sie für dich.
Das Problem ohne DI
// Ohne DI - eng gekoppelt
public class TicketService {
private EmailService emailService = new EmailService();
private PaymentGateway paymentGateway = new StripeGateway();
// Schwer zu testen, schwer zu ändern
}
Mit Spring DI
@Service
public class TicketService {
private final EmailService emailService;
private final PaymentGateway paymentGateway;
// Constructor Injection (empfohlen)
public TicketService(EmailService emailService, PaymentGateway paymentGateway) {
this.emailService = emailService;
this.paymentGateway = paymentGateway;
}
public void purchaseTicket(TicketRequest request) {
paymentGateway.charge(request.getAmount());
emailService.sendConfirmation(request.getEmail());
}
}
Spring erstellt automatisch Instanzen und verbindet sie. Das macht den Code testbar - du kannst in Tests Mock-Objekte injizieren.
Die wichtigsten Stereotyp-Annotationen
@Component- Generische Spring-Komponente@Service- Business-Logik (semantisch wie @Component)@Repository- Datenzugriffs-Schicht@Controller/@RestController- Web-Endpunkte
Alf.io nutzt diese Struktur konsequent. Der TicketReservationManager ist ein @Component, der EventRepository ein Repository-Interface.
REST APIs mit Spring Boot
REST APIs zu bauen ist mit Spring Boot trivial. Ein einfacher Controller:
@RestController
@RequestMapping("/api/events")
public class EventController {
private final EventService eventService;
public EventController(EventService eventService) {
this.eventService = eventService;
}
@GetMapping
public List<Event> getAllEvents() {
return eventService.findAll();
}
@GetMapping("/{id}")
public ResponseEntity<Event> getEvent(@PathVariable Long id) {
return eventService.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@PostMapping
public ResponseEntity<Event> createEvent(@RequestBody @Valid EventRequest request) {
Event created = eventService.create(request);
return ResponseEntity
.created(URI.create("/api/events/" + created.getId()))
.body(created);
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteEvent(@PathVariable Long id) {
eventService.delete(id);
return ResponseEntity.noContent().build();
}
}
Die Annotationen erklären sich fast von selbst:
@RestController= Controller + automatische JSON-Serialisierung@RequestMapping- Basis-Pfad für alle Endpoints@GetMapping,@PostMapping,@DeleteMapping- HTTP-Methoden@PathVariable- Wert aus der URL@RequestBody- JSON-Body zu Objekt@Valid- Validierung aktivieren
ResponseEntity für mehr Kontrolle
ResponseEntity gibt dir Kontrolle über Status-Codes und Headers:
return ResponseEntity
.status(HttpStatus.CREATED)
.header("X-Custom-Header", "value")
.body(event);
Datenbankzugriff mit JPA
Spring Data JPA reduziert Boilerplate-Code für Datenbankzugriffe auf ein Minimum.
Entity definieren
@Entity
@Table(name = "events")
public class Event {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
private String description;
@Column(name = "event_date")
private LocalDateTime eventDate;
@Column(name = "max_tickets")
private Integer maxTickets;
// Getter, Setter, Konstruktoren
}
Repository Interface
Das Besondere an Spring Data: Du schreibst nur ein Interface, Spring generiert die Implementierung.
public interface EventRepository extends JpaRepository<Event, Long> {
// Spring generiert die Query aus dem Methodennamen
List<Event> findByEventDateAfter(LocalDateTime date);
List<Event> findByNameContainingIgnoreCase(String name);
// Oder explizite Query
@Query("SELECT e FROM Event e WHERE e.maxTickets > :minTickets")
List<Event> findEventsWithCapacity(@Param("minTickets") int minTickets);
}
Methoden wie findAll(), findById(), save(), delete() bekommst du kostenlos von JpaRepository.
In Alf.io findest du viele solcher Repositories, etwa das EventRepository für Events oder TicketRepository für Tickets.
Konfiguration und Profile
application.properties
Die zentrale Konfigurationsdatei liegt in src/main/resources/:
# Server
server.port=8080
# Datenbank
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=user
spring.datasource.password=secret
# JPA
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.show-sql=false
Profile für verschiedene Umgebungen
Erstelle application-dev.properties und application-prod.properties:
# application-dev.properties
spring.jpa.show-sql=true
logging.level.org.springframework=DEBUG
# application-prod.properties
spring.jpa.show-sql=false
logging.level.org.springframework=WARN
Aktiviere Profile beim Start:
java -jar app.jar --spring.profiles.active=prod
Alf.io nutzt Profile intensiv: dev für Entwicklung, demo für den Demo-Modus, jdbc-session für Session-Persistierung.
Zusammenfassung
Du hast jetzt die Grundlagen von Spring Boot verstanden:
- Projekt-Setup mit Spring Initializr und Starter Dependencies
- Dependency Injection für lose gekoppelten, testbaren Code
- REST APIs mit @RestController und den Mapping-Annotationen
- Datenbankzugriff mit Spring Data JPA und Repositories
- Konfiguration über Properties und Profile
Der beste Weg zum Lernen ist, echten Code zu lesen. Schau dir Alf.io auf GitHub an - es ist gut strukturiert und dokumentiert.
Im nächsten Teil zeige ich dir, wie du Alf.io auf deinem eigenen Server installierst. Inklusive Java-Setup, PostgreSQL-Konfiguration und den Problemen, die ich auf meinem OVZ7-VServer hatte.
Weiterführende Links:

