CodeGym /Kurse /Spring Boot /Bedingungen und Verhalten basierend auf dem Classpath

Bedingungen und Verhalten basierend auf dem Classpath

Spring Boot
Level 8, Lektion 1
Verfügbar

1. Bedingungen in Spring Boot

Nun ist bereits klar, dass Boot keinen zweiten geheimen Container in die Anwendung zieht: Die Auto-Konfiguration gelangt in denselben ApplicationContext. Die nächste unvermeidliche Frage ist: Anhand welcher Signale entscheidet Boot überhaupt, was genau eingebunden wird?

Beginnen wir mit der Motivation, denn ohne sie wirkt @ConditionalOn... wie eine weitere Annotation, die man „einfach merken“ muss. Bedingungen in Boot sind nicht für die Schönheit da und auch nicht, um Anfängern das Leben schwer zu machen, sondern damit die Plattform irgendwie sicher entscheiden kann, welche Teile der Infrastruktur eingebunden werden sollen und welche nicht – sonst würde die Anwendung zu einem Monstrum werden, das beim Start versucht, buchstäblich alles hochzufahren.

Stellen Sie sich Spring Boot vor wie einen Türsteher am Eingang zum Club „Runtime“. Er muss entscheiden, wen er hineinlässt: Wird Tomcat benötigt? Wird ein JSON-Mapper benötigt? Soll die Web-Schicht aktiviert werden? Sollen bestimmte zusätzliche Funktionen aktiviert werden? Aber er kann nicht einfach „alles einschalten“, denn:

Erstens sind nicht alle Bibliotheken vorhanden. Wenn sich Tomcat nicht im Classpath befindet, ist es sinnlos, die Tomcat-Server-Konfiguration zu aktivieren. Zweitens kann die Anwendung eigene Entscheidungen getroffen haben: Sie haben bereits einen bestimmten Bean erstellt, und Boot sollte keinen zweiten „gleichen“ nachwerfen und einen Streit um @Autowired verursachen. Drittens sollten manche Dinge von den Einstellungen abhängen: zum Beispiel „eine Funktion nur aktivieren, wenn eine bestimmte Eigenschaft gesetzt ist“.

Deshalb verwendet Boot überall Conditions: kleine „Eingangsprüfungen“, die die Frage beantworten: Haben wir das Recht und den Sinn, diese Konfiguration zu aktivieren?

Um sich das Bild besser einzuprägen, hilft es, dies als ein sehr einfaches Flussdiagramm zu betrachten:

flowchart TD
    A["Konfiguration/Auto-Konfiguration möchte Bean hinzufügen"] --> B{"Klasse im Classpath vorhanden?"}
    B -->|nein| X["Überspringen"]
    B -->|ja| C{"Eigenschaft erlaubt?"}
    C -->|nein| X
    C -->|ja| D{"Benötigter Bean existiert bereits?"}
    D -->|ja| X
    D -->|nein| E["Bean registrieren"]

Das sind nicht die „Inneren von Boot“, sondern die grundlegende Entscheidungslogik: Zuerst prüfen, ob es überhaupt etwas gibt, woraus man etwas bauen kann, dann – ob es erlaubt ist, dann – ob wir nicht mit der Anwendung in Konflikt geraten.

2. Classpath und der Einfluss von Abhängigkeiten

Classpath – ein Wort, das zunächst klingt wie „etwas aus einem langweiligen Kapitel über die JVM“, aber in Spring Boot wird es fast zu einem angewandten Werkzeug. Wenn Sie einen Starter oder eine Bibliothek zur build.gradle.kts hinzufügen, vergrößern Sie nicht nur die Größe von build/libs/*.jar. Sie verändern, welche Klassen der Anwendung beim Start zur Verfügung stehen, und damit, welche Conditions ausgelöst werden können.

In Java (vereinfacht) ist der Classpath eine Liste von Orten, an denen die JVM .class-Dateien finden kann. In einem Gradle-Projekt ist das im Wesentlichen das Ergebnis des Builds: Ihr Code plus alle Abhängigkeiten (und die Abhängigkeiten der Abhängigkeiten). Für Boot ist das das „Inventar“ Ihrer Anwendung. Und dann beginnt eine sehr praktische Logik zu wirken: Wenn sich eine bestimmte Klasse im Classpath befindet, dann wollen Sie (höchstwahrscheinlich) das entsprechende Subsystem.

Zum Beispiel ist das Vorhandensein von jakarta.servlet.Servlet und Spring MVC-Klassen ein deutlicher Hinweis: „Wir sind eine Webanwendung auf dem Servlet-Stack“. Das Vorhandensein von Jackson ist ein Hinweis: „Wir wollen Objekte in JSON und zurück umwandeln können“. Das Vorhandensein bestimmter Logging-Bibliotheken ist ein Hinweis: „Das ist der Logging-Stack, der verwendet werden soll“.

Und hier tritt die psychologische Falle für Anfänger auf: Sie haben keinen Code geschrieben, um einen Server zu starten, einen DispatcherServlet zu registrieren oder JSON-Konverter einzurichten – aber sie tauchen auf. Weil Boot sieht, dass diese Klassen verfügbar sind, und schaltet die entsprechenden Konfigurationen ein.

Um diese Idee physisch zu spüren, ist es hilfreich, einmal die „Prüfung auf Vorhandensein einer Klasse“ direkt auf Java-Code-Ebene zu sehen (nicht als „korrekter Boot-Way“, sondern als Demonstration des Gedankens):

import org.springframework.util.ClassUtils;

// Prüfen, ob eine Klasse anhand ihres Namens vorhanden ist: So macht es auch Boot intern in seinen Conditions
boolean mvcPresent = ClassUtils.isPresent(
        "org.springframework.web.servlet.DispatcherServlet",
        ClassUtils.getDefaultClassLoader() // Nimmt den Standard-ClassLoader der Anwendung
);

// Ergebnis ausgeben, um den Classpath als Fakt zu „begreifen“
System.out.println("Spring MVC present = " + mvcPresent); // Spring MVC present = true

Eine lustige Randnotiz: Boot denkt ähnlich, nur in einer akkurateren und massenhaften Form, über @ConditionalOnClass und Konsorten.

3. Landkarte der Bedingungen: Classpath, Properties, Beans

Es folgt eine kleine „Landkarte“, damit Sie nicht alles im Kopf behalten müssen wie eine Ansammlung unzusammenhängender Annotationen. Wichtig ist zu verstehen, dass Spring Boot-Conditions nicht ein einzelner Prüftyp sind, sondern mehrere Familien von Prüfungen, die jeweils eine eigene Frage beantworten. Und ja, heute ist der Hauptakteur der Classpath, aber er ist nicht allein.

Unten finden Sie eine kompakte Tabelle, an die man sich gut erinnert, wenn man ein merkwürdiges Verhalten von Boot sieht und sich fragt: „Aufgrund welches Merkmals hat er das so entschieden?“

Was wird geprüft Welches Signal Typische Boot-Annotation Beispiel in menschlicher Sprache
Vorhandensein einer Klasse classpath @ConditionalOnClass „Es gibt MVC-Klassen im Projekt – also MVC aktivieren“
Fehlen einer Klasse classpath @ConditionalOnMissingClass „Kein Servlet-API – also servlet web runtime nicht aktivieren“
Vorhandensein einer Eigenschaft configuration @ConditionalOnProperty „Feature nur aktiviert, wenn Eigenschaft = true“
Vorhandensein eines Beans Kontext @ConditionalOnBean „Wenn Bean X bereits existiert, kann Y aktiviert werden, das von X abhängt“
Fehlen eines Beans Kontext @ConditionalOnMissingBean „Wenn Sie keinen eigenen Bean erstellt haben – liefere ich einen Standard“

Heute werden wir hauptsächlich über die ersten beiden Zeilen (Classpath-gesteuertes Verhalten) und ein wenig über die dritte (Properties) sprechen, denn in der realen Boot-Entscheidung ist es fast immer eine „Kombination“: Abhängigkeit + Einstellung.

4. @ConditionalOnClass: Aktivierung basierend auf einer Klasse

Nun zum Kernpunkt: @ConditionalOnClass. Diese Annotation ist eine der wichtigsten „Verbindungen“ zwischen Ihrer build.gradle.kts und dem, was tatsächlich im ApplicationContext landet. Und es ist wichtig, sie nicht als „magisches Ding“ zu verstehen, sondern als einen sehr einfachen Gedanken: Wenn die benötigte Bibliothek nicht da ist, tu nicht so, als könntest du damit arbeiten.

Nehmen wir den catalog-service. Stellen wir uns vor, wir möchten einen kleinen Marker-Bean hinzufügen, der nur erscheint, wenn die Anwendung tatsächlich Spring MVC verwendet (also DispatcherServlet im Classpath vorhanden ist). Das ist keine Auto-Konfiguration im Sinne einer Boot-Bibliothek, sondern einfach unser Lern-„Indikator“.

Zuerst erstellen wir das Modell (es ist ganz einfach):

// Einfachstes Modell-Marker: Der Wert wird beim Start ausgegeben
record RuntimeMarker(String value) {
}

Jetzt die Konfiguration, die diesen Marker nur bei Vorhandensein der Klasse erstellt:

import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

// Normale @Configuration, aber mit bedingter Bean-Registrierung
@Configuration
class RuntimeMarkerConfiguration {

    @Bean
    // Bedingung: Bean wird nur erstellt, wenn sich die angegebene Klasse im Classpath befindet
    @ConditionalOnClass(name = "org.springframework.web.servlet.DispatcherServlet")
    RuntimeMarker mvcMarker() {
        // Wert – einfach ein „Indikator“, um das Ergebnis in den Logs zu sehen
        return new RuntimeMarker("spring-mvc");
    }
}

Warum verwenden wir name = "..." und nicht value = DispatcherServlet.class? Weil die Konfiguration so sogar dann kompiliert wird, wenn diese Klasse nicht vorhanden ist. Das ist ein sehr wichtiges technisches Detail: Die Bedingung muss ohne zwingende Compile-Zeit-Abhängigkeit prüfbar sein. Boot macht das in seinen Auto-Konfigurationsklassen oft genauso.

Um das Ergebnis zu sehen, fügen wir eine weitere temporäre Probe-Komponente hinzu. Ihre Aufgabe ist es nicht, ein Teil des permanenten Startup-Codes zu sein, sondern einfach den Fakt zu zeigen: Der Bean ist vorhanden oder nicht.

import java.util.Optional;

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
class RuntimeMarkerRunner implements ApplicationRunner {

    // Optional betont: Der Bean kann fehlen, und das ist in Ordnung
    private final Optional<RuntimeMarker> marker;

    RuntimeMarkerRunner(Optional<RuntimeMarker> marker) {
        this.marker = marker;
    }

    @Override
    public void run(ApplicationArguments args) {
        // Wenn der Bean nicht vorhanden ist, geben wir „none“ aus, damit das Verhalten beobachtbar ist
        System.out.println("Runtime marker = " +
                marker.map(RuntimeMarker::value).orElse("none")); // Runtime marker = spring-mvc
    }
}

Was ist hier wichtig zu bemerken, und das ist direkt die „Denkweise von Boot“:

@ConditionalOnClass entscheidet, ob der Bean überhaupt existiert. Das ist kein if innerhalb einer Methode, es ist eine Entscheidung zur Zeit der Context-Erstellung. Deshalb kann Ihr Code diesen Bean entweder injizieren oder muss auf sein Fehlen vorbereitet sein (mittels Optional, ObjectProvider, verschiedene Profile usw.).

Wenn Sie das zum ersten Mal sehen, fühlt es sich seltsam an: „Warum muss ich darüber nachdenken, ob eine Klasse existiert?“. Aber genau das macht Boot stabil: Es schaltet nichts ein, was physisch nicht funktionieren kann.

5. @ConditionalOnProperty: Aktivierung basierend auf Einstellungen

Der Classpath ist ein starkes Signal, aber nicht immer ausreichend. Manchmal ist die Bibliothek vorhanden, aber eine bestimmte Funktion soll nur aufgrund einer Einstellung aktiviert werden. Sie können zum Beispiel eine Bibliothek für etwas haben, aber einen „Ein/Aus“-Schalter ohne Neukompilierung wünschen. Hier kommt @ConditionalOnProperty ins Spiel.

Hier wird die Property nur als Signal für die Bedingung benötigt. Wir brauchen kein umfangreiches Konfigurationsmodell der Anwendung; es reicht, das Prinzip selbst zu sehen: Ein String-Schlüssel und ein Wert können ebenfalls an der Entscheidung teilhaben, ob ein Bean erstellt wird.

Im catalog-service bauen wir eine kleine Funktion: „Hinweis beim Start ausgeben“, aber nur, wenn die Eigenschaft aktiviert ist.

import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
class StartupHintsConfiguration {

    @Bean
    // Bean nur aktivieren, wenn die Eigenschaft explizit „true“ ist
    @ConditionalOnProperty(name = "app.catalog.startup-hints-enabled", havingValue = "true")
    ApplicationRunner startupHintsRunner() {
        // Hier könnte man sich eine „optionale Funktion“ vorstellen, die an ein Flag gekoppelt ist
        return args -> System.out.println("Hinweis: catalog-service gestartet"); // Hinweis: catalog-service gestartet
    }
}

Um nicht in eine vollständige Konfigurationsebene abzuschweifen, können wir die Eigenschaft temporär direkt im main() als einfachen Schalter für die Bedingung setzen:

import java.util.Map;

import org.springframework.boot.SpringApplication;

public class CatalogServiceApplication {

    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(CatalogServiceApplication.class);

        // Standard-Eigenschaften „als ob aus application.yml“, aber direkt aus Code
        app.setDefaultProperties(Map.of("app.catalog.startup-hints-enabled", "true"));

        // Starte die Anwendung auf die übliche Weise
        app.run(args);
    }
}

Psychologisch ist es nützlich festzuhalten: @ConditionalOnProperty ist ein ebensolcher „Schalter“ wie der Classpath, nur anderer Natur. Der Classpath sagt „Ich habe die Werkzeuge“, die Property sagt „Mir wurde erlaubt / ich wurde gebeten, den Modus einzuschalten“.

6. Kombination von Bedingungen

Einer der Gründe, warum es für einen Anfänger so wirkt, als ob Boot „macht, was es will“, ist, dass die Entscheidung oft von mehreren Bedingungen gleichzeitig abhängt. Sie schauen nur auf die Dependency und denken „Alles klar, das sollte aktiviert werden“, aber Boot prüft noch eine Property. Oder umgekehrt: Sie haben die Property aktiviert, aber die benötigte Bibliothek fehlt. Und Sie bekommen das Gefühl „es ignoriert mich“, obwohl es in Wirklichkeit nur konsequent die Regeln befolgt.

Lassen Sie uns das am selben catalog-service zeigen: Wir erstellen einen CatalogDiagnostics-Bean, der nur erscheint, wenn beide Bedingungen erfüllt sind: Wir sind wirklich eine Webanwendung auf MVC-Basis, und wir haben das Diagnostics-Flag explizit aktiviert.

import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
class DiagnosticsConfiguration {

    @Bean
    // Bedingung 1: Anwendung ist wirklich im MVC/Servlet-Stack (Klasse im Classpath vorhanden)
    @ConditionalOnClass(name = "org.springframework.web.servlet.DispatcherServlet")
    // Bedingung 2: Funktion ist per Einstellung aktiviert
    @ConditionalOnProperty(name = "app.catalog.diagnostics-enabled", havingValue = "true")
    CatalogDiagnostics catalogDiagnostics() {
        // Der Bean selbst ist einfach: Hauptsache, er erscheint/verschwindet je nach Bedingungen
        return new CatalogDiagnostics();
    }
}

// Leere „Feature“-Klasse zur Demonstration: Ihre Anwesenheit im Kontext = Feature aktiviert
class CatalogDiagnostics {
}

Was wir mit diesem Beispiel „ins Gehirn einbrennen“:

Wenn Diagnostics nur im Web-Modus funktionieren sollen, dann ist die Prüfung auf den Classpath ehrlicher, als zu versuchen, irgendwo im Code Fehler abzufangen oder zu prüfen, ob der Server hochgefahren ist. Sie prüfen ein Signal, das für Boot objektiv ist: „MVC-Klassen vorhanden“ bedeutet „es macht Sinn, Web-Diagnostics zu aktivieren“. Und die Property ist das zweite Signal: „Ja, ich will das wirklich“.

Das ist sehr Boot-typisch: nicht ein einziges riesiges „if“ an einer Stelle, sondern die Logik in kleine, prüfbare Bedingungen aufteilen.

7. Starter als Classpath-Schalter

Nun wollen wir alles zu einem praktischen Gedanken zusammenführen, der vor einer Menge Verwirrung schützt. Starter in Spring Boot sind nicht einfach nur „praktische Bibliotheksbündel“. Im Kontext von Conditions ist ein Starter wie ein großer Hebel: Sie haben eine Abhängigkeit hinzugefügt, neue Klassen sind in den Classpath gekommen, also wurden neue @ConditionalOnClass ausgelöst, und plötzlich hat Boot ein ganzes Subsystem eingeschaltet.

In der build.gradle.kts sieht das fast harmlos aus. Zum Beispiel, Sie haben den Web-Starter hinzugefügt – und fertig.

dependencies {
    // WebMVC-Starter hinzugefügt → Servlet/MVC-Klassen erscheinen im Classpath → Auto-Konfigurations-Bedingungen schlagen an
    implementation("org.springframework.boot:spring-boot-starter-webmvc")

    // Test-Starter: zieht Test-Infrastruktur (einschließlich Testabhängigkeiten)
    testImplementation("org.springframework.boot:spring-boot-starter-test")
}

Und zur Laufzeit bedeutet das: Die Anwendung wird von Boot als Servlet-Web-Anwendung betrachtet; ein eingebetteter Server erscheint; MVC-Infrastruktur-Beans erscheinen; eine standardmäßige Verarbeitungskette für HTTP-Anfragen erscheint; Message-Converter und viele andere Dinge erscheinen. Sie müssen das alles nicht von Hand schreiben, weil Boot es bereits für Sie geschrieben hat – aber es schaltet es nicht ein, „weil Boot“, sondern weil jetzt die benötigten Klassen im Classpath sind und die Bedingungen der Auto-Konfiguration zutreffen.

Abhängigkeit hinzugefügt → Classpath geändert → Ergebnisse von @ConditionalOnClass geändert → Menge der aktivierten Konfigurationen geändert → Menge der Beans geändert → Verhalten der Anwendung geändert.

Das ist keine Philosophie. Das erklärt tatsächlich, warum ein einzelner Starter manchmal die Anwendung „zerstört“: Er zerstört sie nicht, er schaltet neue Teile ein, und Sie stoßen unerwartet darauf, dass Ihre Anwendung jetzt eine andere ist (z.B. eine Web-Anwendung geworden ist, obwohl Sie dachten, sie würde „irgendwann mal HTTP können“).

### Mini-Beobachtung im catalog-service

Einen vollständigen Bericht brauchen wir dafür nicht: Wir können eine kleine „Röntgen-Beobachtung“ machen, um weder sich selbst noch Boot blind zu vertrauen. Die Idee ist einfach: Einen Beobachter erstellen, der schaut, welche Beans wirklich da sind, und eine verständliche Meldung ausgibt.

Wir bauen einen kleinen Runner, der versucht, unseren CatalogDiagnostics zu finden und, falls er vorhanden ist, „Ja, Diagnostics sind aktiv“ sagt. Auch dies ist wieder ein einmaliger Probe, kein permanenter Teil des Startup-Codes.

import java.util.Optional;

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
class DiagnosticsProbeRunner implements ApplicationRunner {

    // Optional betont wieder: Der Bean kann fehlen, und das ist ein normaler Zustand
    private final Optional<CatalogDiagnostics> diagnostics;

    DiagnosticsProbeRunner(Optional<CatalogDiagnostics> diagnostics) {
        this.diagnostics = diagnostics;
    }

    @Override
    public void run(ApplicationArguments args) {
        // Beobachten „als Fakt“: Ist das Feature aktiviert oder nicht (basierend auf Bean-Anwesenheit)
        System.out.println("Diagnostics aktiviert = " + diagnostics.isPresent());
        // Diagnostics aktiviert = false
    }
}

Warum ist das für einen Anfänger nützlich? Weil es das „Gefühl von Magie“ nimmt. Sie hören auf zu denken „wahrscheinlich ist es aktiviert“ und beginnen, den Fakt zu sehen: Der Bean existiert entweder oder nicht. Wenn nicht, dann hat eine Bedingung nicht zugetroffen. Wenn ja, dann hat sie zugetroffen.

Und dann kann man der Kette folgen: Welche Bedingung könnte nicht zugetroffen haben? Fehlt eine Abhängigkeit (Classpath)? Ist eine Eigenschaft nicht gesetzt? Ist die Anwendung nicht im richtigen Modus? Und so kommen Sie nach und nach zu einer ingenieurtechnischen Diagnose, nicht zu Schamanismus.

8. Typische Fehler beim Arbeiten mit Bedingungen

Hier gibt es keine „Schreckensgeschichten“, sondern eine Sammlung sehr lebensnaher Situationen, in die fast alle am Anfang tappen. Boot-Bedingungen sind eine einfache Sache, aber das Gehirn eines Anfängers versucht oft, das Modell eines „if im Code“ darauf anzuwenden, und daraus entstehen seltsame Erwartungen.

Fehler Nr. 1: Denken, die Bedingung sei eine „Laufzeitprüfung“ statt eine „Entscheidung zur Context-Erstellung“.
Anfänger erwarten manchmal, dass, wenn man eine Eigenschaft im laufenden Betrieb ändert, der Bean „erscheint“ oder „verschwindet“ in einer laufenden Anwendung. In den meisten Fällen funktioniert das nicht so: @ConditionalOn... entscheidet, ob der Bean beim Start registriert wird. Wenn Sie Dynamik zur Laufzeit wollen – das ist eine ganz andere Architektur, die wir hier nicht brauchen.

Fehler Nr. 2: @ConditionalOnClass(SomeClass.class) auf einer Klasse verwenden, die nicht im Compile-Classpath ist.
Wenn Sie direkt auf die Klasse verweisen, verlangt der Compiler diese Abhängigkeit. Deshalb verwendet man in Bedingungen oft den String name = "...". Das sieht etwas weniger elegant aus, macht die Konfiguration aber universell: Sie kann im Projekt sein, auch wenn die Bibliothek optional ist.

Fehler Nr. 3: Das Verhalten von Boot nur auf eine Ursache zurückführen („Ich habe doch den Starter hinzugefügt!“).
Eine sehr häufige Geschichte: Der Student hat eine Abhängigkeit hinzugefügt und erwartet, dass die Funktion aktiviert wird, hat aber die zweite Bedingung – die Property – nicht beachtet. Oder umgekehrt, er hat die Property aktiviert, aber die Bibliothek nicht hinzugefügt. Am Ende entsteht das Gefühl „Boot hört nicht auf mich“. In der Praxis muss man fast immer eine Kombination von Signalen suchen: Classpath + Properties + (manchmal) Anwesenheit/Abwesenheit von Beans.

Fehler Nr. 4: Bedingte Logik im Business-Code statt bedingter Bean-Registrierung.
Wenn ein Anfänger versteht, dass es ein „Feature ein/aus“ gibt, schreibt er oft ein if (enabled) { ... } im Service, dann nochmal im Controller, dann nochmal woanders. Und es entsteht eine über das ganze Projekt verstreute Logik. Viel sauberer ist es, wenn das Feature als Anwesenheit/Abwesenheit eines Beans ausgedrückt wird und die Abhängigkeiten davon als Optional injiziert werden – dann dokumentiert das Wiring selbst, dass das Feature optional ist, und das ist direkt im Konstruktor sichtbar.

Fehler Nr. 5: „Classpath-gesteuertes Verhalten“ mit „Boot hat sich Business-Logik ausgedacht“ verwechseln.
Boot kann die Infrastruktur aktivieren (Server, MVC, JSON-Konverter, Teile von Integrationen), aber Ihr CourseCatalogService und Ihr Repository wird es nicht erfinden. Wenn der Domänenteil des catalog-service nicht funktioniert, ist es meist sinnlos, das Problem in der Auto-Konfiguration zu suchen: Das ist Ihr Code und Ihr Wiring. Conditions helfen hier nur dabei, das Infrastrukturelle („kommt von Boot“) vom Anwendungsspezifischen („kommt aus dem Projekt“) zu trennen.

1
Aufgabe
Spring Boot, Level 8, Lektion 1
Gesperrt
Marker f\u00fcr das Vorhandensein der MVC-Klasse
Marker f\u00fcr das Vorhandensein der MVC-Klasse
1
Aufgabe
Spring Boot, Level 8, Lektion 1
Gesperrt
Kombination von Classpath und Eigenschaften
Kombination von Classpath und Eigenschaften
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION