Der ApplicationContext ist das Herzstück des Spring
Frameworks und bildet die zentrale Komponente für die Verwaltung und das
Management der Beans in einer Spring-Anwendung. Der
ApplicationContext stellt eine Erweiterung des einfachen
BeanFactory-Containers dar und bietet umfangreiche
Funktionen wie Event-Publishing, Bean-Lifecycle-Management, und vieles
mehr. In diesem Kapitel gehen wir auf die Funktionsweise des
ApplicationContext in Spring Boot ein, erläutern seine
Rolle, seine Konfiguration und wie Sie ihn effektiv in Ihren Anwendungen
nutzen können.
Der ApplicationContext ist eine Implementierung des
Inversion of Control (IoC)-Containers in Spring. Er
übernimmt die Instanziierung, Verwaltung und das Wiring der Beans in
einer Spring-Anwendung. Während BeanFactory nur
grundlegende Funktionen für das Laden und Verwalten von Beans bietet,
erweitert der ApplicationContext diese Funktionalitäten, um
Dinge wie:
In Spring gibt es verschiedene Implementierungen des
ApplicationContext, die je nach Anwendungsfall eingesetzt
werden:
In Spring Boot verwenden wir hauptsächlich den AnnotationConfigApplicationContext, da Spring Boot stark auf Annotations basiert.
In einer typischen Spring Boot-Anwendung wird der
ApplicationContext automatisch beim Start der Anwendung
initialisiert. Spring Boot verwendet den
SpringApplication-Klassenmechanismus, um den
ApplicationContext zu erstellen und zu initialisieren.
Beispiel: Initialisierung des ApplicationContext in einer Spring Boot Anwendung
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}Hier erstellt SpringApplication.run(MyApp.class, args)
automatisch den ApplicationContext und initialisiert alle
Beans.
Jede Bean, die vom ApplicationContext verwaltet wird,
durchläuft einen festen Lifecycle, der mehrere Phasen umfasst:
@PostConstruct oder
InitializingBean.afterPropertiesSet() aufgerufen.@PreDestroy oder DisposableBean.destroy()
aufgerufen.import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.stereotype.Component;
@Component
public class MyService {
public MyService() {
System.out.println("MyService: Konstruktor aufgerufen");
}
@PostConstruct
public void init() {
System.out.println("MyService: Initialisierung");
}
@PreDestroy
public void destroy() {
System.out.println("MyService: Vor der Zerstörung");
}
}In diesem Beispiel wird die Bean MyService beim Start
der Anwendung instanziiert, die Methode init() wird nach
der Dependency Injection aufgerufen, und destroy() wird
kurz vor der Zerstörung der Bean ausgeführt.
Manchmal kann es erforderlich sein, direkt auf den
ApplicationContext zuzugreifen, um bestimmte Funktionen zu
nutzen, wie das Laden von Beans zur Laufzeit oder das Auslösen von
Events.
Sie können den ApplicationContext über
Dependency Injection oder durch Implementieren des
ApplicationContextAware-Interfaces erhalten.
Beispiel: Injection des ApplicationContext
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class MyContextAwareBean implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
public void printAllBeans() {
String[] allBeanNames = applicationContext.getBeanDefinitionNames();
for(String beanName : allBeanNames) {
System.out.println(beanName);
}
}
}Hier wird der ApplicationContext in der Bean
MyContextAwareBean injiziert, wodurch Sie auf alle Beans im
Kontext zugreifen können.
Der ApplicationContext ermöglicht es Ihnen, Beans zur
Laufzeit zu laden, indem Sie deren Namen oder Typen angeben.
Beispiel: Beans zur Laufzeit abrufen
public class MyBeanRetriever {
private final ApplicationContext context;
public MyBeanRetriever(ApplicationContext context) {
this.context = context;
}
public void retrieveBean() {
MyService myService = context.getBean(MyService.class);
myService.doSomething();
}
}In diesem Beispiel wird die Bean MyService dynamisch aus
dem ApplicationContext abgerufen.
Der ApplicationContext unterstützt ein
Event-Handling-System, mit dem Sie Ereignisse veröffentlichen und darauf
reagieren können. Dies ermöglicht die Implementierung einer
Event-getriebenen Architektur.
Sie können eigene Events definieren, die von anderen Komponenten der Anwendung verarbeitet werden.
Beispiel: Definieren und Senden eines benutzerdefinierten Events
import org.springframework.context.ApplicationEvent;
public class MyCustomEvent extends ApplicationEvent {
private final String message;
public MyCustomEvent(Object source, String message) {
super(source);
this.message = message;
}
public String getMessage() {
return message;
}
}Beispiel: Senden des Events
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
@Component
public class EventPublisher {
private final ApplicationEventPublisher eventPublisher;
public EventPublisher(ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
public void publishEvent(String message) {
MyCustomEvent event = new MyCustomEvent(this, message);
eventPublisher.publishEvent(event);
}
}Andere Komponenten können auf diese Events reagieren, indem sie Event-Listener implementieren.
Beispiel: Event-Listener
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class MyEventListener {
@EventListener
public void handleMyCustomEvent(MyCustomEvent event) {
System.out.println("Empfangenes Event: " + event.getMessage());
}
}In diesem Beispiel veröffentlicht der EventPublisher das
MyCustomEvent, und der MyEventListener
empfängt das Event und verarbeitet es.
Vermeiden Sie direkte Abhängigkeiten vom
ApplicationContext: Setzen Sie den
ApplicationContext sparsam ein. Versuchen Sie, Beans durch
Dependency Injection zu verwalten, anstatt direkt auf den
ApplicationContext zuzugreifen.
Nutzen Sie Events gezielt: Verwenden Sie das Event-System, um lose gekoppelte Komponenten zu erstellen, die auf Systemereignisse reagieren. Stellen Sie sicher, dass Events nicht für enge Kopplungen zwischen Komponenten genutzt werden.
Laden Sie Beans zur Laufzeit nur wenn nötig:
Laden Sie Beans zur Laufzeit aus dem ApplicationContext
nur, wenn es unvermeidbar ist. Dies kann die Übersichtlichkeit des Codes
verschlechtern.
Der ApplicationContext ist eine zentrale Komponente im
Spring-Framework, die nicht nur das Lifecycle-Management und die
Verwaltung von Beans übernimmt, sondern auch Funktionen wie
Event-Handling und Internationalisierung unterstützt. In Spring Boot
wird der ApplicationContext automatisch initialisiert und
verwaltet, wodurch die Konfiguration und Handhabung von Beans
erleichtert wird. Durch die Nutzung der Möglichkeiten des
ApplicationContext können Sie flexible, erweiterbare und
wartbare Anwendungen entwickeln.