In Spring Boot sind Beans zentrale Bausteine, die durch den Spring IoC (Inversion of Control)-Container verwaltet werden. Eine Bean ist ein Objekt, das vom Spring-Framework instanziiert, konfiguriert und verwaltet wird. Beans repräsentieren die Komponenten und Services einer Spring-Anwendung und interagieren miteinander, um die gewünschte Geschäftslogik auszuführen.
In diesem Kapitel werden wir untersuchen, was Beans in Spring Boot sind, wie sie definiert, verwaltet und genutzt werden, und welche Rolle sie im IoC-Container spielen. Dabei gehen wir auf ihre Lebenszyklen, Konfigurationen und die wichtigsten Annotationen ein.
Eine Bean in Spring ist ein Objekt, das vom Spring IoC-Container verwaltet wird. Beans werden typischerweise in einer Konfigurationsdatei (z.B. XML oder Java-Konfiguration) definiert oder über Annotationen in den Quellcode eingefügt. Der IoC-Container übernimmt die Verwaltung von Beans, einschließlich ihrer Abhängigkeiten, ihres Lebenszyklus und ihrer Sichtbarkeit innerhalb der Anwendung.
Beans in Spring Boot können durch Annotationen oder manuelle
Konfiguration erstellt und verwaltet werden. In der Regel werden Beans
in Spring Boot mithilfe von Annotationen wie @Component,
@Service, @Repository oder
@Controller definiert.
Spring Boot verwendet standardmäßig eine Annotation-basierte Konfiguration. Beans werden automatisch vom Spring Framework erkannt und instanziiert, wenn die Klasse mit einer der oben genannten Annotationen versehen ist.
@ComponentDie Annotation @Component wird verwendet, um eine Klasse
als Bean zu markieren, die vom IoC-Container verwaltet werden soll.
Beispiel: Bean-Definition mit
@Component
import org.springframework.stereotype.Component;
@Component
public class MyComponent {
public String getMessage() {
return "Hello, Spring Boot!";
}
}In diesem Beispiel wird die Klasse MyComponent als Bean
registriert, die automatisch vom IoC-Container instanziiert wird.
Spring bietet mehrere Stereotyp-Annotationen, die spezialisierte
Formen von @Component sind. Diese Annotationen erleichtern
die Semantik und das Verständnis des Codes:
Beispiel: Bean-Definition mit
@Service
import org.springframework.stereotype.Service;
@Service
public class MyService {
public void performAction() {
System.out.println("Geschäftslogik wird ausgeführt.");
}
}@BeanEs ist auch möglich, Beans manuell in einer Konfigurationsklasse zu
definieren. Dazu verwendet man die @Bean-Annotation in
einer Klasse, die mit @Configuration annotiert ist.
Beispiel: Manuelle Bean-Definition
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public MyComponent myComponent() {
return new MyComponent();
}
}In diesem Fall wird die myComponent-Bean explizit in der
Konfigurationsklasse AppConfig definiert.
Jede Bean in Spring durchläuft einen festen Lebenszyklus, der vom IoC-Container verwaltet wird. Dieser Lebenszyklus umfasst mehrere Phasen, die sicherstellen, dass die Beans korrekt instanziiert, konfiguriert und schließlich zerstört werden.
Um Initialisierungs- und Zerstörungsmethoden in einer Bean zu
definieren, können die Annotationen @PostConstruct und
@PreDestroy verwendet werden.
Beispiel: Bean-Initialisierung und -Zerstörung
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.stereotype.Component;
@Component
public class MyComponent {
@PostConstruct
public void init() {
System.out.println("Bean wurde initialisiert.");
}
@PreDestroy
public void destroy() {
System.out.println("Bean wird zerstört.");
}
}In diesem Beispiel wird die Methode init() nach der
Instanziierung der Bean aufgerufen, und die Methode
destroy() wird vor der Zerstörung der Bean ausgeführt.
In Spring gibt es verschiedene Scopes, die bestimmen, wie oft eine Bean instanziiert wird. Die beiden häufigsten Scopes sind:
Standardmäßig sind Beans in Spring als Singleton
definiert. Das bedeutet, dass nur eine Instanz der Bean pro
ApplicationContext erstellt wird.
Beispiel: Singleton-Scope
import org.springframework.stereotype.Component;
@Component
public class SingletonBean {
public SingletonBean() {
System.out.println("SingletonBean wird instanziiert.");
}
}Diese Bean wird nur einmal instanziiert, auch wenn sie mehrfach in verschiedenen Klassen injiziert wird.
Wenn eine Bean bei jeder Anforderung neu instanziiert werden soll,
kann der Prototype-Scope verwendet werden. Dazu wird
die Annotation @Scope("prototype") verwendet.
Beispiel: Prototype-Scope
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("prototype")
public class PrototypeBean {
public PrototypeBean() {
System.out.println("PrototypeBean wird instanziiert.");
}
}In diesem Fall wird eine neue Instanz der PrototypeBean
jedes Mal erstellt, wenn sie angefordert wird.
Beans interagieren miteinander durch Dependency Injection. Dies ermöglicht es, Abhängigkeiten zwischen Komponenten zu verwalten, ohne sie direkt in den Klassen zu instanziieren. Spring Boot bietet verschiedene Möglichkeiten zur Durchführung von Dependency Injection, wie in dem Kapitel „Dependency Injection“ beschrieben.
Die Konstruktor-Injection wird in Spring als bevorzugte Methode angesehen, da sie sicherstellt, dass alle Abhängigkeiten bei der Instanziierung der Bean bereitgestellt werden.
Beispiel: Konstruktorbasierte Injection
import org.springframework.stereotype.Component;
@Component
public class OrderService {
private final PaymentService paymentService;
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
public void processOrder() {
paymentService.processPayment();
}
}Hier wird die PaymentService-Bean über den Konstruktor
injiziert.
In einer Spring-Anwendung können mehrere Beans desselben Typs
definiert sein. In diesem Fall wird der @Qualifier
verwendet, um anzugeben, welche spezifische Bean verwendet werden
soll.
Beispiel: Verwendung von @Qualifier
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@Component
public class OrderService {
private final PaymentService paymentService;
public OrderService(@Qualifier("paypalService") PaymentService paymentService) {
this.paymentService = paymentService;
}
public void processOrder() {
paymentService.processPayment();
}
}In diesem Beispiel wird die spezifische
paypalService-Bean injiziert, obwohl es möglicherweise
mehrere PaymentService-Implementierungen gibt.
Spring Beans können auch mit Parametern oder Konfigurationen versehen werden, die zur Laufzeit gesetzt werden. Dies geschieht oft in Konfigurationsklassen, in denen beans erstellt und konfiguriert werden.
Beispiel: Bean mit Parametern
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public MyComponent myComponent() {
MyComponent myComponent = new MyComponent();
myComponent.setParameter("Wert");
return myComponent;
}
}Hier wird die Bean myComponent manuell konfiguriert,
bevor sie dem ApplicationContext hinzugefügt wird.
Beans sind fundamentale Bausteine in jeder Spring- und Spring Boot-Anwendung. Sie stellen die zentralen Komponenten dar, die vom IoC-Container verwaltet werden, und interagieren miteinander durch Dependency Injection. Durch die Verwendung von Beans wird der Code flexibler, wiederverwendbarer und leichter testbar. Spring bietet verschiedene Mechanismen zur Verwaltung und Konfiguration von Beans, einschließlich Singleton- und Prototype-Scopes, Initialisierungs- und Zerstörungslogik sowie der Definition von Abhängigkeiten zwischen Beans.