Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Observer-Reihenfolge und Priorität steuern

Observer-Reihenfolge und Priorität steuern

~6 Min. Lesezeit Zuletzt aktualisiert am 9. August 2026

Kapitel 35 zeigte, dass ein einziges Event mehrere unabhängige Observer haben kann - mironsoft_loyalty_customer_tier_changed könnte gleichzeitig ein Marketing-Modul UND ein Analytics-Modul interessieren. Was, wenn deren Reihenfolge zueinander tatsächlich wichtig ist? Die kurze Antwort: events.xml kennt - anders als Plugins - kein explizites sortOrder-Attribut. Dieses Kapitel erklärt, wovon die Reihenfolge stattdessen abhängt.

Reihenfolge innerhalb einer Datei

Registriert dieselbe events.xml-Datei mehrere <observer>-Knoten für dasselbe <event>, laufen sie exakt in der Reihenfolge, in der sie im Dokument stehen - top-down, vorhersehbar.

Reihenfolge über Module hinweg

Registrieren zwei verschiedene Module je einen Observer auf dasselbe Event, bestimmt die Modul-Ladereihenfolge die Ausführungsreihenfolge - dieselbe topologische Sortierung aus den <sequence>-Einträgen in module.xml, die auch di.xml- und Layout-Merges steuert. Ein Modul, das nach Mironsoft_Loyalty laden soll, trägt es einfach in seine eigene sequence ein:

<!-- app/code/Vendor/Analytics/etc/module.xml, illustrativ -->
<module name="Vendor_Analytics">
    <sequence>
        <module name="Mironsoft_Loyalty"/>
    </sequence>
</module>

Damit ist garantiert, dass Vendor_Analytics' Observer auf mironsoft_loyalty_customer_tier_changed immer nach einem eventuellen eigenen Observer von Mironsoft_Loyalty auf demselben Event läuft - ohne eine einzige Zeile events.xml selbst anzufassen.

Das name-Attribut als Merge-Schlüssel

Zwei <observer>-Knoten mit demselben name - auch aus verschiedenen Modulen - werden zu einem einzigen zusammengeführt, exakt wie bei Block- und Layout-XML. Ein später ladendes Modul kann so einen fremden Observer per disable="true" abschalten oder seine instance überschreiben, ohne dessen Quellcode zu verändern.

<!-- Ein Observer eines anderen Moduls gezielt deaktivieren, illustrativ -->
<event name="mironsoft_loyalty_customer_tier_changed">
    <observer name="vendor_marketing_notify_tier_upgrade" disable="true"/>
</event>

Das shared-Attribut

Standardmäßig (shared="true", implizit) wiederverwendet Magento eine einzige Observer-Instanz für alle Dispatches - unkritisch für AwardPointsOnOrderPlaced und ReversePointsOnCreditmemoSave, da beide ausschließlich über Konstruktor-Injection arbeiten und keinerlei veränderlichen Zustand zwischen zwei Aufrufen halten - dieselbe Zustandslosigkeit, die PointsCalculator (Kapitel 5) von Anfang an auszeichnet. shared="false" erzwingt eine frische Instanz je Dispatch und wäre nur relevant, wenn ein Observer tatsächlich eigenen, veränderlichen Zustand zwischen execute()-Aufrufen hält - in diesem Modul kommt das nirgends vor.

Wenn Reihenfolge wirklich zählt

  1. Modul-sequence anpassen (siehe oben) - wirkt sich aber auf alle geteilten Events zwischen den beiden Modulen aus, nicht nur den einen, der gerade wichtig ist.
  2. Beide Anliegen in einem einzigen Observer bündeln, statt sich auf eine Reihenfolge zwischen zwei getrennten Observern zu verlassen - eliminiert das Problem, kostet aber Entkopplung.
  3. Wirklich reihenfolgekritische Logik in ein Plugin verschieben, das ein explizites, numerisches sortOrder kennt (Kapitel 37 leitet direkt dorthin über).

Tipp: Diese drei Optionen sind eine Rangfolge, keine gleichwertige Auswahl: Option 1 zuerst versuchen, Option 2 nur bei echter inhaltlicher Kohäsion beider Anliegen, Option 3 als letztes Mittel, wenn Reihenfolge tatsächlich Kernanforderung ist - nicht bloß eine bequeme Annahme.

Damit endet Block 4 inhaltlich fast - Kapitel 37 fasst die gesamte, bisher implizite Entscheidung "Observer oder Plugin?" explizit zusammen, bevor Block 5 mit Plugins im Detail beginnt.