Spring verwaltet den gesamten Lebenszyklus einer Bean – von der Geburt bis zum Tod. Für den Einstieg reicht ein grobes Verständnis dieses Prozesses.
Eine Bean ist ein Objekt, das Spring verwaltet. Nicht jedes Objekt in deiner Anwendung ist eine Bean. Nur die, die Spring kennt und kontrolliert.
Die Domain-Klassen Score, Player,
Game sind keine Beans. Du erzeugst sie selbst mit
new. Die Service-, Repository- und Controller-Klassen sind
Beans. Spring erzeugt und verwaltet sie.
Vereinfacht durchläuft jede Bean diese Phasen:
Phase 1 – Klassensuche: Spring scannt Packages nach
Klassen mit bestimmten Annotationen (@Component,
@Service, etc.).
Phase 2 – Instanziierung: Spring ruft den Konstruktor auf und erzeugt das Objekt.
Phase 3 – Injection: Spring setzt die Abhängigkeiten – per Konstruktor, Setter oder Feld.
Phase 4 – Initialisierung: Methoden mit
@PostConstruct werden aufgerufen.
Phase 5 – Zerstörung: Beim Herunterfahren werden
Methoden mit @PreDestroy aufgerufen.
Manchmal muss eine Bean nach der Injection noch etwas tun. Dafür gibt
es @PostConstruct:
@Service
public class GameCatalogService {
private final GameRepository gameRepository;
private Map<String, Game> gameCache;
public GameCatalogService(GameRepository gameRepository) {
this.gameRepository = gameRepository;
// Hier ist gameRepository noch nicht gesetzt bei Field Injection!
}
@PostConstruct
public void initialize() {
// Wird aufgerufen, NACHDEM alle Abhängigkeiten gesetzt sind
this.gameCache = gameRepository.findAll().stream()
.collect(Collectors.toMap(Game::getId, g -> g));
log.info("Game cache initialized with {} games", gameCache.size());
}
}Die Reihenfolge ist garantiert:
@PostConstruct-Methode wird aufgerufenIm Konstruktor sind bei Field oder Setter Injection die
Abhängigkeiten noch null. In @PostConstruct
sind sie garantiert gesetzt.
Manche Beans halten Ressourcen, die beim Beenden freigegeben werden müssen:
@Service
public class ConnectionPoolService {
private ExecutorService executor;
@PostConstruct
public void init() {
executor = Executors.newFixedThreadPool(10);
log.info("Connection pool started");
}
@PreDestroy
public void cleanup() {
executor.shutdown();
log.info("Connection pool shut down");
}
}Spring ruft @PreDestroy automatisch beim Herunterfahren.
Du musst nicht selbst auf Shutdown-Hooks achten.
Standardmäßig existiert jede Bean genau einmal. Egal wie oft sie injiziert wird – es ist immer dieselbe Instanz.
Drei Controller, eine Service-Instanz. Das ist effizient und in den meisten Fällen das gewünschte Verhalten.
@Service // Default: Singleton
public class HighscoreService {
// Diese Instanz wird mit allen Controllern geteilt
}Es gibt andere Scopes (Prototype, Request, Session), aber für den Einstieg ist Singleton der einzig relevante.
Für die tägliche Arbeit reicht dieses Wissen:
| Konzept | Bedeutung |
|---|---|
| Bean | Von Spring verwaltetes Objekt |
| Singleton | Eine Instanz pro Anwendung (Default) |
@PostConstruct |
Wird nach Injection aufgerufen |
@PreDestroy |
Wird vor dem Herunterfahren aufgerufen |
Die Details des Lifecycles – BeanPostProcessor, InitializingBean, DisposableBean – sind fortgeschrittene Themen. Sie werden relevant, wenn du eigene Frameworks schreibst oder Spring erweitern willst.
Für Anwendungsentwicklung gilt: Spring kümmert sich. Du definierst die Beans, Spring verwaltet sie. Vertraue dem Container.