„Wenn ein Arbeiter seine Arbeit gut machen will, muss er zuerst seine Werkzeuge schärfen.“ – Konfuzius, „Die Gespräche des Konfuzius. Lu Linggong“
Titelseite > Programmierung > Umkehrung der Kontrolle im Spring Framework

Umkehrung der Kontrolle im Spring Framework

Veröffentlicht am 06.11.2024
Durchsuche:388

Inversion of Control in Spring Framework

Inversion of Control (IoC) und Dependency Injection (DI) sind zwei grundlegende Konzepte im Spring Framework. Traditionell sind Objekte für die Erstellung und Verwaltung ihrer eigenen Abhängigkeiten verantwortlich. IoC dreht diese Verantwortung jedoch um, indem es die Kontrolle über die Objekterstellung und das Abhängigkeitsmanagement an ein Framework wie Spring übergibt.

Diese Verschiebung bietet mehrere Vorteile:

  • Einfacherer Implementierungsaustausch: Verschiedene Implementierungen können mit minimalen Änderungen an der Codebasis ausgetauscht werden.
  • Erhöhte Modularität: Anwendungskomponenten werden modularer, was die Trennung von Belangen erleichtert.
  • Verbesserte Testbarkeit: Komponenten können isoliert getestet werden, was Mocking und andere Teststrategien vereinfacht.

IoC kann über verschiedene Mechanismen implementiert werden, einschließlich Entwurfsmustern wie dem Factory Pattern, Strategy Pattern oder Service Locator Pattern. Der gebräuchlichste und leistungsstärkste Weg, IoC zu erreichen, ist jedoch die Abhängigkeitsinjektion.

Abhängigkeitsinjektion verstehen

Dependency Injection (DI) ist eine Technik, bei der das Framework Abhängigkeiten in ein Objekt einfügt, anstatt dass das Objekt die Abhängigkeiten selbst erstellt. Es gibt verschiedene Arten von DI im Frühling:

  • Konstruktorinjektion: Abhängigkeiten werden über den Konstruktor der Klasse bereitgestellt.
  • Setter-Injektion: Abhängigkeiten werden durch Setter-Methoden injiziert.
  • Feldinjektion: Abhängigkeiten werden mithilfe von Annotationen direkt Feldern zugewiesen.

In einer einfachen Serviceklasse könnten Sie beispielsweise Folgendes sehen:

@Service
public class OrderService {

    private final PaymentService paymentService;

    @Autowired
    public OrderService(PaymentService paymentService) {
        this.paymentService = paymentService;
    }

    public void processOrder(Order order) {
        paymentService.processPayment(order.getPaymentDetails());
    }
}

Hier wird PaymentService über die Konstruktorinjektion in OrderService eingefügt, was im Allgemeinen aufgrund seiner klaren Abhängigkeiten und der einfachen Testbarkeit bevorzugt wird.

IoC-Container: BeanFactory vs. ApplicationContext

Spring stellt einen IoC-Container bereit, der für die Verwaltung des Lebenszyklus von Beans (von Spring verwaltete Objekte) verantwortlich ist. Die grundlegende Schnittstelle für diesen Container ist BeanFactory. Die meisten Anwendungen verwenden jedoch ApplicationContext, der BeanFactory erweitert und zusätzliche Funktionen bietet.

BeanFactory

  • Basis-IoC-Container: Er bietet grundlegende Funktionen zum Erstellen und Verwalten von Beans.
  • Lazy Initialization: Beans werden erstellt, wenn sie zum ersten Mal angefordert werden.

Anwendungskontext

  • Erweiterter IoC-Container: Zusätzlich zu den Grundfunktionen von BeanFactory bietet es:
    • Unterstützung für Internationalisierung (i18n)
    • Ereignisweitergabe und -behandlung
    • Asynchrone Anforderungsbearbeitung
    • Integration mit aspektorientierter Programmierung (AOP)
  • Eagere Initialisierung: Beans können beim Start der Anwendung instanziiert werden, sodass sie sofort verfügbar sind.

Beispiel:

// Getting a bean from the ApplicationContext
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
MyBean myBean = context.getBean(MyBean.class);

In diesem Beispiel wird ApplicationContext zum Abrufen einer Bean verwendet. Wenn Sie eine einfache BeanFactory verwenden würden, würde diese eine ähnliche Funktionalität bieten, jedoch ohne die zusätzlichen Vorteile von ApplicationContext.

Zugriff auf den ApplicationContext

Es gibt zwei gängige Möglichkeiten, auf den aktuellen ApplicationContext zuzugreifen:

  1. Autowired: Fügen Sie den ApplicationContext direkt in Ihre Komponente ein.

    @Autowired
    private ApplicationContext applicationContext;
    
  2. ApplicationContextAware: Implementieren Sie die ApplicationContextAware-Schnittstelle, mit der Sie den ApplicationContext nach Bedarf abrufen können.

    public class MyBean implements ApplicationContextAware {
        private ApplicationContext applicationContext;
    
        @Override
        public void setApplicationContext(ApplicationContext context) throws BeansException {
            this.applicationContext = context;
        }
    }
    

Lebenszyklus einer Spring-Anwendung

Wenn eine Spring-Anwendung startet, finden eine Reihe von Schritten statt:

  1. Verarbeiten von Umgebungsvariablen und -eigenschaften: Das Umgebungsobjekt wird erstellt und enthält Einstellungen aus application.properties oder application.yml.

  2. Erstellen des ApplicationContext: Der entsprechende ApplicationContext-Typ wird ermittelt und instanziiert. Beispielsweise kann eine Spring Boot-Anwendung AnnotationConfigServletWebServerApplicationContext für Java-basierte Konfigurationen verwenden.

  3. Bean-Definitionen laden: Spring lädt Bean-Definitionen aus mehreren Quellen, z. B. annotierte Klassen, @Configuration-Klassen oder XML-Dateien. Jede Bean-Definition enthält Informationen zu Typ, Umfang, Abhängigkeiten und Lebenszyklus-Callbacks der Bean.

  4. Verarbeitung von BeanFactoryPostProcessors: Diese Prozessoren ändern die Bean-Definitionen, bevor die eigentlichen Beans erstellt werden.

  5. Abhängigkeitsauflösung und Bean-Erstellung: Der ApplicationContext löst Abhängigkeiten auf und erstellt die Beans. Wenn eine Bean Abhängigkeiten von anderen Beans hat, werden diese Abhängigkeiten zuerst erstellt.

Bean Scopes im Frühling

Spring unterstützt verschiedene Bean-Bereiche, die den Lebenszyklus und die Sichtbarkeit einer Bean innerhalb des Containers definieren:

  • Singleton (Standard): Eine einzelne Instanz der Bean wird für den gesamten Anwendungskontext erstellt.
  • Prototyp: Bei jeder Anforderung der Bean wird eine neue Instanz erstellt.
  • Anfrage: Für jede HTTP-Anfrage (Webanwendungen) wird eine neue Bean-Instanz erstellt.
  • Sitzung: Für jede HTTP-Sitzung (Webanwendungen) wird eine neue Bean-Instanz erstellt.

Beispiel:

@Bean
@Scope("prototype")
public MyPrototypeBean myPrototypeBean() {
    return new MyPrototypeBean();
}

In diesem Beispiel wird jedes Mal eine neue MyPrototypeBean-Instanz erstellt, wenn sie vom Container angefordert wird.

Proxy-Objekte in Bean-Scopes

Stellen Sie sich ein Szenario vor, in dem eine Bean mit Singleton-Bereich von einer Bean mit Prototype-Bereich abhängt. Normalerweise würde die Prototyp-Bean nur einmal während der Initialisierung des Singletons erstellt. Um sicherzustellen, dass jedes Mal eine neue Instanz der Prototyp-Bean bereitgestellt wird, verwendet Spring Proxy-Objekte.

Beispiel mit Proxys:

@Component
@Scope(value = "singleton")
public class SingletonBean {

    @Autowired
    @Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
    private PrototypeBean prototypeBean;

    public void showMessage() {
        System.out.println(prototypeBean.getMessage());
    }
}

Hier stellt ScopedProxyMode.TARGET_CLASS sicher, dass bei jedem Aufruf von getMessage() eine neue PrototypeBean-Instanz zurückgegeben wird.

Unterschied zwischen Spring Framework und Spring Boot

Spring Boot ist eine Erweiterung des Spring Frameworks, die die Einrichtung und Entwicklung neuer Spring-Anwendungen vereinfacht. Es bietet:

  • Eingebettete Anwendungsserver: Führen Sie Spring-Anwendungen ganz einfach als eigenständige Apps mit eingebettetem Tomcat, Jetty oder Undertow aus.
  • Automatische Konfiguration: Konfiguriert Beans automatisch basierend auf dem Klassenpfad und anderen Einstellungen.
  • Vereinfachte Verpackung: Verpacken Sie Anwendungen als ausführbare JARs oder WARs.
  • Integrierte Überwachung und Integritätsprüfungen: Integrierte Endpunkte zur Überwachung der Gesundheit und des Status der Anwendung.

Automatische Konfiguration in Spring Boot

Auto-Configuration ist eine leistungsstarke Funktion in Spring Boot, die viele Dinge basierend auf den Abhängigkeiten in Ihrem Klassenpfad für Sie konfiguriert. Dies wird durch bedingte Anmerkungen wie:

gesteuert.
  • @ConditionalOnClass
  • @ConditionalOnMissingClass
  • @ConditionalOnBean
  • @ConditionalOnMissingBean

Beispiel:

Wenn Sie beispielsweise Jackson in Ihrem Klassenpfad haben, konfiguriert Spring Boot automatisch einen ObjectMapper für die JSON-Serialisierung:

@Configuration
@ConditionalOnClass(ObjectMapper.class)
public class JacksonAutoConfiguration {
    // Configuration details...
}

Wenn ObjectMapper vorhanden ist, wird diese Konfiguration automatisch angewendet. Andernfalls wird es übersprungen.

Aktive Autokonfigurationen anzeigen

Sie können die aktiven automatischen Konfigurationen während des Startvorgangs protokollieren, indem Sie Folgendes zu Ihren application.properties hinzufügen:

logging.level.org.springframework.boot.autoconfigure=DEBUG

Dadurch wird ein detaillierter Bericht erstellt, der zeigt, welche Konfigurationen angewendet wurden und welche nicht, was Ihnen bei der Fehlerbehebung oder dem Verständnis der Anwendungskonfiguration hilft.

Abschluss

Inversion of Control und Dependency Injection sind Kernkonzepte, die die Flexibilität, Modularität und Testbarkeit ermöglichen, die Spring so leistungsstark machen. Wenn Sie verstehen, wie der IoC-Container von Spring funktioniert, wie Beans verwaltet werden und wie Spring Boot diese Funktionen erweitert, können Sie robuste, wartbare Anwendungen effizienter entwickeln.

Freigabeerklärung Dieser Artikel ist abgedruckt unter: https://dev.to/be11amer/inversion-of-control-in-spring-framework-4mc0?1 Bei Verstößen wenden Sie sich bitte an [email protected], um ihn zu löschen
Neuestes Tutorial Mehr>

Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.

Copyright© 2022 湘ICP备2022001581号-3