3 Spring als Architekturprinzip

Die meisten Frameworks liefern Funktionen. Eine Logging-Bibliothek schreibt Logs. Eine HTTP-Bibliothek macht HTTP-Requests. Eine JSON-Bibliothek parst JSON. Diese Frameworks sind Werkzeuge – du rufst eine Methode auf, bekommst ein Ergebnis.

Spring funktioniert fundamental anders. Es liefert keine einzelne Funktion, sondern eine Art zu programmieren. Spring ist weniger Werkzeugkasten als Bauplan.

3.1 Das Problem ohne Architektur

Stell dir vor, du schreibst eine Anwendung ohne Framework. Du brauchst verschiedene Komponenten: Eine Klasse für die Geschäftslogik, eine für den Datenbankzugriff, eine für die Benutzeroberfläche. Diese Komponenten müssen miteinander kommunizieren.

Der naive Ansatz sieht so aus:

public class HighscoreService {
    
    private MySQLDatabase database = new MySQLDatabase("localhost", 3306, "arcade");
    private EmailClient emailClient = new EmailClient("smtp.example.com");
    
    public void saveScore(String player, int points) {
        database.insert("INSERT INTO scores VALUES (?, ?)", player, points);
        
        if (points > 10000) {
            emailClient.send("admin@example.com", "Neuer Highscore!", player + ": " + points);
        }
    }
}

Dieser Code hat mehrere Probleme, die auf den ersten Blick nicht offensichtlich sind.

Das erste Problem ist die Testbarkeit. Um den HighscoreService zu testen, brauchst du eine echte MySQL-Datenbank und einen echten SMTP-Server. Unit-Tests werden unmöglich. Integrationstests werden langsam und fragil.

Das zweite Problem ist die Austauschbarkeit. Was, wenn die Produktion PostgreSQL statt MySQL verwendet? Oder MongoDB? Du müsstest den Code ändern. Was, wenn du in der Entwicklungsumgebung keine E-Mails versenden willst? Wieder Code ändern.

Das dritte Problem ist die Modularisierung. Der HighscoreService weiß zu viel. Er kennt Datenbankdetails (Host, Port), er kennt E-Mail-Server-Konfiguration. Diese Informationen gehören nicht in eine Geschäftslogik-Klasse.

3.2 Inversion of Control

Spring löst diese Probleme durch ein Prinzip namens Inversion of Control (IoC). Der Name klingt akademisch, die Idee ist simpel: Komponenten beschaffen sich ihre Abhängigkeiten nicht selbst. Stattdessen werden ihnen die Abhängigkeiten von außen geliefert.

@Service
public class HighscoreService {
    
    private final ScoreRepository repository;
    private final NotificationService notifications;
    
    public HighscoreService(ScoreRepository repository, NotificationService notifications) {
        this.repository = repository;
        this.notifications = notifications;
    }
    
    public void saveScore(String player, int points) {
        repository.save(new Score(player, points));
        
        if (points > 10000) {
            notifications.notifyHighscore(player, points);
        }
    }
}

Der Unterschied ist subtil aber entscheidend. Der HighscoreService weiß nicht mehr, welche Datenbank verwendet wird. Er kennt nur das Interface ScoreRepository. Er weiß nicht, wie Benachrichtigungen versendet werden – per E-Mail, Push-Notification oder Slack. Er kennt nur NotificationService.

3.3 Warum das wichtig ist

Diese Umkehrung der Kontrolle ermöglicht Dinge, die vorher unmöglich waren.

Testbarkeit: In Unit-Tests injizierst du Mock-Objekte statt echter Implementierungen. Der Test läuft in Millisekunden, ohne externe Abhängigkeiten.

Flexibilität: In der Entwicklung nutzt du eine eingebettete H2-Datenbank. In der Produktion MongoDB. Der HighscoreService bleibt unverändert.

Modularität: Jede Komponente hat eine klar definierte Verantwortung. Änderungen an der Datenbankschicht betreffen nicht die Geschäftslogik.

3.4 Mehr als eine Technik

Inversion of Control ist nicht einfach eine clevere Programmiertechnik. Es ist ein Architekturprinzip, das die gesamte Struktur einer Anwendung beeinflusst. Es zwingt dich, in Abstraktionen zu denken. Es fördert lose Kopplung. Es macht Code wiederverwendbar.

Spring hat dieses Prinzip nicht erfunden – die Idee stammt aus den 1980er Jahren. Aber Spring hat es massentauglich gemacht. Vor Spring war IoC eine akademische Übung. Mit Spring wurde es zum Industriestandard.

Wenn du Spring lernst, lernst du nicht nur ein Framework. Du lernst eine Denkweise, die dich zu einem besseren Entwickler macht.