CodeGym /Kurse /Spring Boot /Condition evaluation delta in Boot

Condition evaluation delta in Boot

Spring Boot
Level 19, Lektion 3
Verfügbar

1. Zweck der Condition Evaluation Delta

Wenn DevTools aktiviert ist, leben Sie im Modus „korrigiert → gespeichert → Ergebnis angesehen". Das ist großartig, solange alles offensichtlich ist. Sobald Sie jedoch etwas Infrastrukturelles ändern (Bean, Profil, Konfiguration), erfolgt der Neustart schnell, aber die Ursache für die Verhaltensänderung zu verstehen – das ist langsam. Die Condition Evaluation Delta ist der Versuch von Spring Boot, Ihnen einen „Git Diff" zu geben, aber nicht für Dateien, sondern für Auto-Configuration-Entscheidungen: was vor dem Neustart als passend angesehen wurde und was danach als passend gilt.

Um das Problem zu verstehen, stellen Sie sich eine typische Situation vor: Sie haben einen winzigen @Bean hinzugefügt, und nach dem Neustart ist plötzlich das Standardverhalten von Boot „irgendwo verschwunden". Die Logs sind groß, Sie scrollen, finden viele Zeilen über Tomcat, MVC, JSON, und sehen trotzdem keine Erklärung. Genau hier macht die Delta die Sache menschlich: Sie erzählt nicht den gesamten Startvorgang neu, sondern zeigt nur die Änderungen in den Conditional Matches zwischen zwei Zuständen.

Es ist wichtig, einen subtilen Punkt zu verstehen: Die Delta handelt nicht davon, „welche Beans erstellt wurden" (obwohl dort indirekt oft die Konsequenz sichtbar ist), sondern davon, welche Bedingungen true/false geworden sind und warum Boot ein Stück Auto-Configuration aktiviert oder deaktiviert hat. Das heißt, es ist weniger ein Werkzeug für Geschwindigkeit als vielmehr für Verständnis.

2. Was DevTools vergleicht

Damit die Delta nicht wie eine weitere mysteriöse Textwand aussieht, ist es hilfreich, ein einfaches Modell im Kopf zu behalten. Boot hat eine Reihe von Auto-Configuration-Klassen, und jede dieser Klassen ist wie ein „Konfigurationspaket", das nur aktiviert wird, wenn bestimmte Bedingungen erfüllt sind. Es gibt verschiedene Bedingungstypen, aber in der Praxis werden Sie am häufigsten auf drei stoßen: Prüfung auf das Vorhandensein einer Klasse im classpath, Prüfung auf das Vorhandensein eines Beans im ApplicationContext und Prüfung eines Property-Werts. Aus diesen Bedingungen setzt Boot die Antwort auf die Frage zusammen: „Aktivieren wir dies oder nicht?".

Intern hat Boot eine Zusammenfassung, die genau aufzeichnet: welche Auto-Configuration aktiviert wurde, welche nicht, und aus welchem Grund. Diese Zusammenfassung wird üblicherweise Condition Evaluation Report genannt – dem Sinne nach ein Bericht darüber, wie die Bedingungen ausgewertet wurden. DevTools nimmt den Bericht „vorher", nimmt den Bericht „nachher" und gibt die Differenz – Delta – aus. Es ist genau ein Diff: was im vorherigen Zustand vorhanden war, was nicht mehr da ist; und was im neuen Zustand hinzugekommen ist.

Anschaulich kann man sich das so vorstellen:

flowchart TD
    A[Sie ändern Code/Konfiguration] --> B[DevTools führt Neustart durch]
    B --> C[Boot sammelt Condition Evaluation Report]
    C --> D[DevTools vergleicht: vorheriger Report vs neuer Report]
    D --> E[In den Logs erscheint CONDITIONS EVALUATION DELTA]
    E --> F[Sie verstehen: welche Bedingung hat sich geändert und warum]

Und hier sofort ein nützlicher technischer Gedanke: Die Delta beantwortet nicht die Frage „was ist kaputt", sondern die Frage „welche Entscheidung von Boot hat sich geändert". Das ist manchmal sogar wichtiger als Fehler, denn ein Fehler ist ein Ereignis, eine Entscheidungsänderung ist die Ursache.

3. Aktivierung und Suche der Delta in den Logs

Die Delta hat eine sehr praktische Eigenschaft: Sie erscheint nach einem Neustart, nicht „jede Sekunde". Wenn Sie also statisches HTML geändert und ein Reload erhalten haben, werden Sie keine Delta sehen – denn die Auto-Configuration-Bedingungen wurden nicht neu bewertet, der Kontext wurde nicht neu erstellt. Die Delta ist eine Geschichte über den Neustart und nur über den Neustart. Daher sind für sie genau die Änderungen relevant, die tatsächlich den ApplicationContext und seine Zusammenstellung beeinflussen.

In den Logs wird die Delta normalerweise durch eine sehr auffällige Überschrift hervorgehoben. In der Praxis werden Sie mit den Augen nach einem Block etwa dieser Art suchen (das Format kann abweichen, aber der Sinn ist derselbe):

============================
CONDITIONS EVALUATION DELTA
============================

Wenn die Delta anfängt zu stören (z.B. Sie machen viele kleine Änderungen und möchten diesen Block nicht ständig sehen), kann man sie mit einer DevTools-Einstellung deaktivieren. Die sauberste Variante ist, dies im lokalen Profil zu halten, damit die allgemeine Projektkonfiguration nicht zu einer Sammlung von Developer Convenience wird:

# src/main/resources/application-local.yaml
spring:
  devtools:
    restart:
      log-condition-evaluation-delta: false

Wenn Sie es wieder rückgängig machen möchten, setzen Sie einfach true oder entfernen den Schlüssel – und Sie kehren zum Standardverhalten zurück. Das Wichtigste: Machen Sie diese Eigenschaft nicht zur Religion. Die Delta ist ein nützlicher Scheinwerfer, aber manchmal leuchtet er direkt in die Augen.

4. Lesen der Delta: was hat sich geändert und warum

Die Delta wie „ein weiteres Startlog" zu lesen, ist fast garantiert sinnlos. Der funktionierende Ansatz ist ein anderer: Zuerst formulieren Sie, was genau Sie geändert haben, und dann suchen Sie in der Delta genau nach dem Bedingungstyp, der darauf reagiert haben sollte. Wenn Sie einen @Bean hinzugefügt haben, ist es logisch, Änderungen von Bedingungen wie @ConditionalOnMissingBean zu erwarten. Wenn Sie das Profil umgeschaltet haben, ist es logisch zu erwarten, dass sich Property-Bedingungen oder einfach das Vorhandensein Ihrer Konfigurationsklassen ändern. Wenn Sie nur die Geschäftslogik in einem Service geändert haben, kann die Delta leer sein – und das ist normal.

Es ist hilfreich, diese kleine Tabelle „Änderung → was sich in der Delta meistens bewegt" im Kopf zu behalten:

Was Sie geändert haben Was sich in der Delta normalerweise ändert Welche Schlussfolgerung Sie ziehen können
Einen @Bean im Projekt hinzugefügt @ConditionalOnMissingBean matcht nicht mehr in Auto-Config Boot ist zurückgetreten, hat statt des Defaults Ihre Einstellung übernommen.
Ihren @Bean entfernt Früher matchte Auto-Config nicht, jetzt matcht sie Boot ist zu den Defaults zurückgekehrt
Profil gewechselt (local → dev) Bedingungen, die von Properties oder dem Profil abhängen, haben ihr Ergebnis geändert Das Profil wurde tatsächlich aktiviert oder nicht, nicht nur „scheinbar"
Ein YAML-Property geändert, das Bedingungen beeinflusst @ConditionalOnProperty hat den Match geändert Das Property wird tatsächlich gelesen und hat den erwarteten Wert

Ein weiterer wichtiger Punkt: Die Delta bedeutet nicht unbedingt „schlecht". Sie kann Negative Matches enthalten, und das ist überhaupt kein Fehler. Es ist oft einfach eine Feststellung: „früher war die Bedingung true, jetzt ist sie false, weil Sie einen Bean hinzugefügt haben". In einem guten Boot-Projekt passiert das ständig, und es ist ein normaler Teil der gesteuerten Anpassung.

5. Szenario: Eigenen Bean hinzugefügt – Boot ist „zurückgetreten"

Der klassischste Fall, in dem die Delta wirklich Zeit spart: Sie haben Ihren eigenen Infrastruktur-Bean hinzugefügt (bewusst oder zufällig), und ein Teil der Auto-Configuration wurde nicht mehr aktiviert, weil Boot nach dem Prinzip funktioniert: „Wenn Sie es explizit konfiguriert haben, mische ich mich nicht ein". Das ist das Backoff-Modell, das wir bereits besprochen haben. Das Problem ist, dass Sie ohne die Delta manchmal nicht verstehen, welchen Default Boot nicht mehr anwendet und warum.

Nehmen wir den catalog-service und machen absichtlich ein Lehrbeispiel: Wir fügen vorübergehend einen eigenen ObjectMapper (oder genauer JsonMapper, der ein Nachkomme von ObjectMapper ist) hinzu, um das Backoff-Modell in der Delta zu sehen. Gleich eine Warnung im Stil von „damit es später nicht weh tut": Einen solchen Override als dauerhafte lokale Einstellung zu behalten, ist nicht nötig. Uns geht es hier nicht um den Mapper selbst, sondern darum, wie die Delta die Änderung der Boot-Entscheidung zeigt.

Fügen wir eine Konfiguration hinzu, die nur im local-Profil aktiv ist, damit das Experiment kontrolliert bleibt:

package com.example.catalogservice.support.jackson;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.json.JsonMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

@Configuration // Wird von Component Scan erfasst: dies ist eine normale Spring-Konfiguration
@Profile("local") // Aktiviert diese Konfiguration nur im lokalen Profil, um das Experiment nicht weiterzutragen
public class LocalJacksonConfiguration {

    @Bean // Erstellen unseren eigenen ObjectMapper: damit zwingen wir Boot, von der Standard-JacksonAutoConfiguration "zurückzutreten"
    public ObjectMapper objectMapper() {
        // Eigener Mapper, um den Effekt des Backoff-Modells in der Delta zu sehen
        return JsonMapper.builder()
                .findAndAddModules() // Automatisch Module hinzufügen (z.B. JavaTimeModule für java.time.*)
                .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) // Daten werden "menschlicher" serialisiert
                .build(); // Fertigen ObjectMapper erstellen
    }
}

Beachten Sie zwei Dinge. Erstens liegt die Klasse innerhalb des Root-Pakets der Anwendung (com.example.catalogservice...), also wird sie vom Component Scan erfasst. Zweitens macht @Profile("local") diesen Bean „umschaltbar": in local ist er vorhanden, in dev und prod nicht.

Nach dem Speichern der Datei wird DevTools einen Neustart durchführen (weil es eine Java-Code-Änderung ist), und in den Logs sehen Sie die Delta. In lehrreicher Form könnte sie so aussehen:

============================
CONDITIONS EVALUATION DELTA
============================

Negative matches:
----------------
JacksonAutoConfiguration:
   Did not match:
      - @ConditionalOnMissingBean (types: com.fasterxml.jackson.databind.ObjectMapper)
        found bean 'objectMapper' (OnBeanCondition)

Der Sinn ist buchstäblich zu lesen: „JacksonAutoConfiguration ist nicht mehr passend, weil die Bedingung @ConditionalOnMissingBean(ObjectMapper) nicht erfüllt ist – der Bean objectMapper ist bereits vorhanden". Und genau das wollten wir als Lehr-Effekt erreichen: Boot sagt ehrlich, warum es seinen eigenen Standard-ObjectMapper nicht erstellt.

Es gibt auch eine sehr praxisnahe, erwachsene Schlussfolgerung. Wenn Sie jemals einen ObjectMapper hinzugefügt haben und sich plötzlich das Datumsformat oder die Enum-Serialisierung geändert hat – die Delta liefert oft die erste Erklärung, wo genau „der Hebel umgelegt" wurde. Und ja, das ist der Fall, in dem eine kleine Konfiguration das Verhalten der gesamten JSON-Schicht ändern kann. Daher ist das Backoff-Modell ein mächtiges Werkzeug, aber die Verantwortung liegt auch wirklich bei Ihnen. Sobald Sie diesen Effekt gesehen haben, entfernen Sie besser die LocalJacksonConfiguration, damit das lokale Profil wieder mit der normalen Boot-JSON-Konfiguration lebt.

6. Szenario: Profilwechsel

Profile in Boot sind eine wunderbare Sache, aber tückisch. Wunderbar, weil sie erlauben, lokale Bequemlichkeiten getrennt zu halten. Tückisch, weil Sie manchmal denken, dass local aktiv ist, aber in Wirklichkeit ist default gestartet, und Sie streiten eine halbe Stunde mit dem Monitor, warum „die Einstellung nicht funktioniert". Die Condition Evaluation Delta ist in solchen Fällen fast wie ein Zeuge: Sie zeigt, was aktiviert und was deaktiviert wurde, und zwar genau aufgrund der geänderten Bedingungen.

Setzen wir unser Beispiel mit LocalJacksonConfiguration fort. Im local-Profil ist der Bean objectMapper vorhanden, und Boot tritt von seiner JacksonAutoConfiguration zurück. Sobald Sie das local-Profil verlassen oder diesen temporären Bean einfach entfernen, sollte die Delta beim nächsten Neustart das umgekehrte Bild zeigen: Die Auto-Configuration matcht wieder, weil Missing Bean wieder true ist.

Aus logischer Sicht sieht es so aus: Im dev-Profil gibt es keinen Ihren ObjectMapper → die Bedingung @ConditionalOnMissingBean(ObjectMapper) ist wieder erfüllt → Boot aktiviert seine Auto-Configuration wieder.

Ein konditionaler Ausschnitt der Delta könnte so aussehen:

============================
CONDITIONS EVALUATION DELTA
============================

Positive matches:
----------------
JacksonAutoConfiguration:
   Matched:
      - @ConditionalOnMissingBean (types: com.fasterxml.jackson.databind.ObjectMapper)
        did not find any beans (OnBeanCondition)

Jetzt wird die Delta zu einem sehr konkreten Signal: „Bei diesem Start geht Boot wieder davon aus, dass ObjectMapper fehlt, also wird es den Default erstellen". Und das ist nicht nur für Jackson nützlich. Genauso können Sie Profiländerungen in MVC-Einstellungen, in bedingten enabled/no-op-Beans und an allen Stellen erkennen, an denen das Verhalten von der Umgebung abhängt.

Und wieder eine wichtige Nuance: Die Delta ersetzt nicht Ihr Verständnis der Profile, verkürzt aber den Weg von „scheinbar nicht das richtige Profil" zu „ja, wirklich nicht das richtige Profil" enorm. Beim Lernen spart das Nerven, bei der Arbeit Stunden. Und den temporären Override entfernt man nach einer solchen Überprüfung besser, damit local keine unnötige JSON-Anpassung mit sich schleppt.

7. Delta und Framework Takeover in MVC

Manchmal führen Studenten, und ehrlich gesagt nicht nur Studenten, versehentlich eine kleine Revolution im Spring Boot-Projekt durch. Das häufigste Szenario: Jemand fügt eine zu „starke" MVC-Anpassung hinzu, und Boot beginnt, Teile seiner Defaults zu deaktivieren. Im Kurs halten wir bewusst die Grenze: Wir passen MVC über WebMvcConfigurer an, aber wir aktivieren nicht @EnableWebMvc, weil dies oft zu einem Framework Takeover führt. Und die Delta ist eines der Werkzeuge, das hilft, diesen Takeover nicht anhand der Symptome zu erkennen („warum funktionieren plötzlich statische Ressourcen nicht?"), sondern anhand der Ursache („warum wurde die Auto-Configuration deaktiviert?").

Selbst wenn Sie solche Experimente nicht planen, ist es nützlich, das Prinzip zu verstehen. Die Auto-Configuration-Klasse WebMvcAutoConfiguration hat normalerweise eine Bedingung wie: „aktiviere dich, wenn niemand seine eigene vollständige MVC-Konfiguration mitgebracht hat". Wenn Sie eine zu schwere Konfiguration mitbringen, sieht Boot das und tritt zurück. Die Delta zeigt in solchen Fällen oft eine abrupte Bewegung: Eine große Auto-Configuration ist in Negative Matches gewechselt, aufgrund von OnBeanCondition.

Und das ist methodisch wichtig. Wenn Sie in der Delta sehen, dass eine ganze Schicht der Auto-Configuration nicht mehr matcht, ist das fast immer ein Grund, innezuhalten und sich zu fragen: „Wollte ich wirklich die Boot-Defaults deaktivieren, oder wollte ich nur einen kleinen Formatierer oder Konverter hinzufügen?" In unserem Kurs ist die richtige Antwort normalerweise die zweite. Und die Delta hilft, den Moment zu erwischen, in dem Sie versehentlich das Erste getan haben.

8. Disziplin beim Lesen der Delta

Die Delta ist eine informative Sache, aber sie hat einen geschwätzigen Modus, besonders wenn Sie Änderungen vorgenommen haben, die viele Auto-Configuration-Klassen betreffen. In solchen Momenten verfällt man leicht in das Lesen des Logs wie eines Romans: „Positive Matches… Negative Matches…" und nach fünf Minuten merken Sie, dass Sie nichts verstanden haben, aber sehr müde sind. Damit die Delta für Sie und nicht gegen Sie arbeitet, braucht sie Disziplin.

Der erste Trick: Lesen Sie die Delta nicht von oben nach unten, sondern suchen Sie nach bekannten Wörtern. Fast immer kennen Sie bereits den Bereich der Änderung: JSON, MVC, Profile, bestimmte @Configuration-Klassen von Ihnen. Also suchen Sie in der Delta nach den entsprechenden Auto-Configuration-Namen oder Bedingungstypen. Der zweite Trick: Denken Sie daran, dass die Delta den Unterschied zwischen zwei Zuständen zeigt. Wenn Sie sich nicht erinnern, was Sie vor dem Neustart genau gemacht haben, wirkt die Delta wie Magie, weil Sie die zweite Hälfte des Diffs – das „Vorher" – verloren haben.

Der dritte Trick: Erlauben Sie sich, die Delta vorübergehend zu deaktivieren, wenn Sie an einer Aufgabe arbeiten, bei der sie nicht hilft. Zum Beispiel korrigieren Sie die reine Geschäftslogik der Kursfilterung in CourseCatalogService, und jeder Neustart wird von einer Delta begleitet, die faktisch leer oder nicht relevant ist. Ausgeschaltet – Arbeit erledigt – wieder eingeschaltet. Das ist keine Schwäche. Es ist die normale Anpassung der Werkzeuge an die Aufgabe, nicht die Aufgabe an die Werkzeuge.

9. Typische Fehler beim Arbeiten mit der Delta

Fehler Nr. 1: Die Delta als Fehlerlog lesen und sich vor dem Wort „Negative" fürchten.
In der Delta bedeuten Negative Matches meistens kein Problem, sondern eine Tatsache: Diese Auto-Configuration wird jetzt nicht angewendet, weil die Bedingung nicht erfüllt ist. In Boot ist das ein normaler Teil der Backoff-Mechanik. Der Fehler beginnt, wenn Sie jedes Negative als Defekt betrachten und anfangen, etwas zu reparieren, das überhaupt nicht kaputt ist.

Fehler Nr. 2: Versuchen, die Delta zu verstehen, ohne festgehalten zu haben, was genau Sie geändert haben.
Die Delta ist ein Diff. Wenn Sie sich nicht an die „linke Seite" – den vorherigen Zustand – erinnern, wird die „rechte Seite" zu einem Haufen mysteriöser Zeilen. Das passiert besonders häufig, wenn Sie mehrere Änderungen hintereinander gemacht haben: YAML angepasst, einen Bean hinzugefügt, das Profil umgeschaltet, und dann versuchen, die Delta zu lesen, als wäre es eine einzige Ursache. In diesem Modus hilft sie nicht.

Fehler Nr. 3: Erwarten, dass die Delta auf jede Dateiänderung reagiert.
Die Delta erscheint nach einem Neustart, nicht nach einem Reload. Wenn Sie eine statische Ressource oder etwas geändert haben, das DevTools ohne Neuerstellung des Kontexts aktualisiert hat, muss die Delta nicht erscheinen. Manchmal denken Studenten „die Delta funktioniert nicht", obwohl es tatsächlich keinen Neustart gab. Das ist kein Bug – das ist die Logik des Werkzeugs.

Fehler Nr. 4: Einen „lehrreichen" Infrastruktur-Override machen und vergessen, dass er den gesamten Service beeinflusst.
Das Beispiel mit ObjectMapper ist sehr aussagekräftig: Sie haben einen Bean hinzugefügt – und die gesamte JSON-Schicht hat sich geändert. Die Delta sagt in diesem Fall ehrlich „Boot ist zurückgetreten", aber sie rettet nicht vor den Konsequenzen, wenn Sie nicht verstehen, was genau Sie abgefangen haben. Daher sollte man Overrides der Infrastruktur entweder sehr vorsichtig oder strikt mit dem Profil @Profile("local") einschränken, um das Experiment nicht versehentlich dorthin zu tragen, wo es nicht benötigt wird.

Fehler Nr. 5: Die Delta zu früh deaktivieren, weil „zu viel Text".
Ja, die Delta kann laut sein. Aber oft wird sie erst nach ein paar Mal bewusstem Lesen verständlich. Wenn Sie sie beim ersten Unbehagen deaktivieren, verlieren Sie eine der bequemsten Brücken zwischen „ich habe etwas geändert" und „Boot hat eine andere Entscheidung getroffen". Hier ist es besser, nicht zu heldenhaft zu sein, aber auch nicht zu kapitulieren: Lesen Sie sie an ein oder zwei einfachen Fällen, und dann wird sie wie ein Hinweis funktionieren, nicht wie eine Strafe.

1
Aufgabe
Spring Boot, Level 19, Lektion 3
Gesperrt
Delta nach Hinzufügen eines eigenen ObjectMapper
Delta nach Hinzufügen eines eigenen ObjectMapper
1
Aufgabe
Spring Boot, Level 19, Lektion 3
Gesperrt
Delta beim Umschalten der Property
Delta beim Umschalten der Property
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION