CodeGym /Kurse /Spring Core /Setter und method injection in Spring

Setter und method injection in Spring

Spring Core
Level 7, Lektion 2
Verfügbar

1. Wann Setter/Method-Injection sinnvoll ist

Wenn Sie gerade die constructor injection lieben gelernt haben (das ist eine normale Entwicklungsphase eines Spring-Entwicklers), dann mögen setter injection und method injection wie „wozu brauchen wir ein zweites Lenkrad im Auto, wenn das erste funktioniert“ wirken. Aber in der realen Entwicklung gibt es manchmal Situationen, in denen der Konstruktor entweder unbequem oder nicht verfügbar ist – und dann werden die Methoden zu einem sauberen Kompromiss, nicht zu einer „schlechten Angewohnheit“.

Und noch eine kurze Klarstellung zum Begriff: In dieser Vorlesung meinen wir mit method injection die Verwendung von @Autowired auf einer beliebigen Konfigurationsmethode. lookup-method / @Lookup – ein anderer, seltenerer Mechanismus, den wir jetzt nicht brauchen.

Beginnen wir mit dem Wichtigsten: setter injection und method injection sind immer noch Dependency Injection, nur der Injektionspunkt ist ein anderer. Anstatt „alles zum Zeitpunkt der Objekterstellung zu erhalten“, machen wir „erzeugen und dann einen Teil der Abhängigkeiten in einem separaten Schritt erhalten“. Dies nennt man zweistufige Objektkonstruktion, und sie ist sinnvoll, wenn eine Klasse ein obligatorisches Grundgerüst und zusätzliche Einstellungen/Kollaborateure hat, die logisch „hinterher“ kommen.

Ein anschauliches Beispiel (aus einer Welt ohne @Autowired): Sie kaufen einen Tisch. Der Konstruktor besteht aus Beinen und Tischplatte (ohne sie ist es kein Tisch). Aber der Untersetzer, die Dekolampe und das Mauspad sind bereits „Nachrüstung“. Man kann auch ohne sie leben. Und genau bei solcher „Nachrüstung“ sind Methoden/Setter-Ansätze meist sinnvoll.

In unserem Lernprojekt ContextFlow kommt eine ähnliche Logik ebenfalls vor. Bei Services auf der Ebene „eine Bestellung aufgeben“ sollten obligatorische Abhängigkeiten klar sichtbar sein – im Konstruktor. Bei unterstützenden Infrastrukturobjekten (Berichtsdruck, Formatierung, Konsolenausgabe) möchte man manchmal ein Standardverhalten bereitstellen und die Möglichkeit haben, es sauber über den Container zu überschreiben.

Um die Grenze im Kopf zu behalten, kann man eine einfache Regel merken, die fast wie eine Verkehrsregel klingt: Wenn eine Klasse ohne eine Abhängigkeit nicht ihre Hauptarbeit erledigen kann, dann ist es eine Abhängigkeit für den Konstruktor. Wenn die Abhängigkeit das Verhalten ändert, die Klasse aber auch ohne sie funktionsfähig bleibt (oder sie zur „Konfiguration“ gehört), dann ist ein Methoden/Setter ein Kandidat.

2. Setter-Injection: Mechanik und Preis

Setter injection sieht einfach aus: Spring erstellt ein Objekt und ruft dann eine Methode mit dem Namen setXxx(...) auf und übergibt einen passenden Bean. Auf der Mechanikebene ähnelt das sehr einem „Feld zuweisen“, aber der wichtige Punkt ist, dass die Zuweisung nach dem Konstruktor erfolgt. Das heißt, die Klasse existiert eine Zeit lang in einem Zustand „ich bin bereits geboren, aber noch nicht vollständig konfiguriert“. Manchmal ist das in Ordnung, aber manchmal ein direkter Weg zu seltsamen Bugs.

Das lehrbuchhafteste Beispiel einer Setter-Injection sieht so aus:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class ReportPrinter {
    // Die Abhängigkeit wird NACH dem Konstruktor auftreten (im Moment des Setter-Aufrufs durch den Container)
    private ReportFormatter formatter;

    @Autowired
    public void setFormatter(ReportFormatter formatter) {
        // Spring wird diese Methode nach der Objekterstellung aufrufen und einen passenden Bean übergeben
        this.formatter = formatter;
    }
}

Beachten Sie: Formal kann ReportPrinter mit new ReportPrinter() erstellt werden. Aber wenn Sie danach sofort eine Methode aufrufen, die formatter verwendet, erhalten Sie entweder einen NullPointerException oder eine „leere“ Arbeit – je nachdem, wie der Code geschrieben ist. Das ist der Hauptpreis der setter injection: Das Objekt kann sich in einem inkorrekten Zustand befinden, bis der Container seinen Teil der Arbeit erledigt hat.

Um dies zu veranschaulichen, fügen wir minimale Funktionalität hinzu und sehen, wie leicht man sich „das Bein brechen“ kann, wenn man das Objekt manuell erstellt:

public class ReportPrinter {
    // Vor der Injektion ist dieses Feld null
    private ReportFormatter formatter;

    public String print(String raw) {
        // Wenn das Objekt manuell erstellt wird (new), kann formatter null bleiben → NPE
        return formatter.format(raw);
    }
}

Innerhalb des Spring-Kontexts tritt dies normalerweise nicht auf (der Container gibt Ihnen keinen Bean, bevor er die Injektion abgeschlossen hat). Aber in plain Java-Code tritt es leicht auf. Und hier ist ein wichtiger praktischer Gedanke: Setter-Injection ist meist dort gerechtfertigt, wo Sie die Reihenfolge des Objektlebens kontrollieren (z. B. das Objekt wird vom Container erstellt und nur über den Container verwendet).

Wie macht man Setter-Injection „sicherer“ für das Leben? Eine einfache Technik ist, der Klasse ein vernünftiges Standardverhalten zu geben, damit sie ohne „Nachrüstung“ leben kann. Dann wird Setter-Injection nicht zu „das Objekt funktionsfähig machen“, sondern zu „das Objekt verbessern/konfigurieren“.

Zum Beispiel: ReportPrinter kann standardmäßig mit einfacher Formatierung arbeiten, aber der Container kann einen intelligenteren Formatierer einfügen:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class ReportPrinter {
    // Standardverhalten: das Objekt ist auch ohne Spring-Container lebensfähig
    private ReportFormatter formatter = new TextReportFormatter(); // fallback

    @Autowired
    public void setFormatter(ReportFormatter formatter) {
        // Wenn Spring einen Bean des Formatierers gefunden hat, überschreibt er den Standard
        this.formatter = formatter;
    }
}

Ja, hier gibt es ein „kleines new innerhalb der Klasse“, und wir wollen dies nicht zum Stil für Business-Services machen. Aber als Lehrdemo für eine infrastrukturelle Helper-Klasse ist es nützlich: Sie spüren, warum Setter-Injection manchmal für „Overrides“ verwendet wird, nicht für obligatorische Teile. Dies ist genau die Variante mit einem sicheren Standardzustand. Für eine obligatorische Post-Construction-Abhängigkeit ist ein solcher Fallback nicht geeignet: Der Preis der zweistufigen Konstruktion muss sichtbar bleiben.

Jetzt eine wichtige Frage: Warum lebt Setter-Injection überhaupt noch in einer Welt, in der es Konstruktoren gibt? Neben den „optionalen Einstellungen“ gibt es noch zwei pragmatische Motive.

Der erste Grund ist eine fremde oder Legacy-Klasse, die Sie nicht ändern können. Es kommt vor, dass ein Objekt keinen bequemen Konstruktor hat, dafür aber einen Satz von Setter-Methoden (klassischer JavaBeans-Stil). Wenn es sich um eine externe Bibliothek handelt, können Sie keinen „Konstruktor mit Abhängigkeiten hinzufügen“. Dann sammelt die Spring-Konfiguration das Objekt notgedrungen über „erstellt → konfiguriert“.

Der zweite Grund ist ein sehr überladener Konstruktor bei einem Infrastrukturobjekt, bei dem ein Teil der Parameter Einstellungen sind, keine Abhängigkeiten. Für den Servicelayer ist ein langer Konstruktor ein Signal „die Klasse macht zu viel“. Aber für einen „Berichtsdruck-Manager“ können einige Parameter tatsächlich Konfiguration sein: Verzeichnis, Dateipräfix, Überschreibmodus usw. In solchen Objekten ist der Setter-Ansatz historisch häufiger anzutreffen.

Wenn Sie in Versuchung geraten zu sagen „na dann auch in den Services“, erinnern Sie sich an Lecture 1: Der Servicelayer im Projekt ist der Ort, an dem wir maximale Vorhersagbarkeit wollen. Dort verliert Setter-Injection fast immer an Lesbarkeit.

3. Method-Injection: Flexible Konfiguration über Methoden

Method injection in unserem heutigen Sinne ist, wenn Spring eine Abhängigkeit nicht über einen „Setter nach Namen“ injiziert, sondern über eine beliebige Methode, die mit @Autowired markiert ist. Technisch gesehen wird Spring diese Methode nach der Objekterstellung trotzdem aufrufen; der Methodenname muss nur nicht mit set beginnen. Dieser kleine Unterschied bringt einen großen Vorteil: Sie können die Methode so benennen, dass sie die Bedeutung der Konfiguration widerspiegelt, nicht wie eine „normale Eigenschaftsänderung“ aussieht.

Ein einfaches Beispiel:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class NotificationGateway {
    // Die Abhängigkeit, die man als „bei Start konfiguriert“ wahrnehmen möchte
    private NotificationSender sender;

    @Autowired
    public void configureSender(NotificationSender sender) {
        // Das ist kein „jeden Dienstag ändern“, sondern „einmal beim Zusammenbau konfiguriert“
        this.sender = sender;
    }
}

Das ist immer noch „Injektion über eine Methode“, liest sich aber anders. setSender(...) verspricht unterschwellig, dass der Absender jeden Dienstag geändert werden kann. Aber configureSender(...) sagt: „das ist ein Konfigurationsschritt, der einmal beim Zusammenbau stattfinden sollte“.

Die zweite nützliche Eigenschaft der Method-Injection: Die Methode kann mehrere Parameter akzeptieren, und das macht das Wiring manchmal kohärenter. Zum Beispiel, wenn Sie Einstellungen explizit in einem Schritt gruppieren möchten, anstatt 5 separate Setter-Methoden zu erzeugen.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class AuditPipeline {
    // Beide Abhängigkeiten werden in einem „Konfigurations“-Schritt gesetzt
    private AuditWriter writer;
    private AuditMessageFormatter formatter;

    @Autowired
    public void configure(AuditWriter writer, AuditMessageFormatter formatter) {
        // Spring fügt beide Beans nach dem Konstruktor hier ein
        this.writer = writer;
        this.formatter = formatter;
    }
}

Aus Sicht des „reinen DI-Stils“ sollten obligatorische Abhängigkeiten immer noch im Konstruktor bleiben. Aber als Technik für die Infrastruktur kann es angemessen sein: Die Methode configure(...) zeigt explizit, dass dies ein Bauabschnitt ist, kein „Felder irgendwo aktualisieren“.

Hier ist es wichtig, ein nützliches Werkzeug nicht mit einem „neuen Standard“ zu verwechseln. Method injection ersetzt nicht constructor injection, sondern schließt eine Nische: saubere Post-Constructor-Konfiguration, ehrlichere Namen, die Möglichkeit, Parameter in einem Schritt zu gruppieren.

Wenn Sie das Gefühl haben, dass Sie anfangen, „alles über configure()“ zu schreiben, ist das ein Alarmzeichen. Normalerweise bedeutet es, dass Sie entweder das normale Design der Klasse umgehen oder versuchen, obligatorische Abhängigkeiten vor dem Leser zu verstecken. In diesem Moment ist es besser, innezuhalten und sich zu fragen: „Warum ist das kein Konstruktor?“

4. Lebenszyklus eines Beans und Reihenfolge der Injektionen

Wenn Sie zum ersten Mal @Autowired auf einer Methode sehen, entsteht der natürliche (und sehr menschliche) Wunsch zu fragen: „Okay, wann ruft Spring es eigentlich auf?“ Sie müssen nicht den gesamten Container-Pipeline durchgehen, aber ein grundlegendes Bild ist nützlich, sonst fühlt sich Setter/Method-Injection wie Magie an, nicht wie ein vorhersagbarer Schritt.

Vereinfacht sieht der Lebensweg eines typischen Singleton-Beans so aus: Der Container erstellt das Objekt (der Konstruktor wird ausgeführt), dann werden die Abhängigkeiten befüllt (hier werden die @Autowired-Methoden und Setter aufgerufen), dann wird die „Initialisierungs“-Phase ausgeführt, und erst danach gilt der Bean als fertig und kann normal an der Anwendung teilnehmen. Für uns heute ist ein Fakt wichtig: Konstruktor ist immer zuerst, @Autowired-Methoden danach.

Schematisch kann man es so darstellen:

flowchart TD
    A["Objekterstellung (constructor)"] --> B["Abhängigkeitsinjektion über @Autowired-Methoden/Setter"]
    B --> C["Bean-Initialisierung (nach Injektion)"]
    C --> D["Bean bereit und für andere verfügbar"]

Um die Reihenfolge buchstäblich mit den Augen zu sehen, kann man eine Mini-Demo mit System.out.println(...) machen. Das ist Lehrcode, aber er beantwortet perfekt die Frage „wann genau?“:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class WiringOrderDemo {

    public WiringOrderDemo() {
        // 1) Zuerst wird immer der Konstruktor ausgeführt
        System.out.println("1) constructor");
    }

    @Autowired
    public void setAuditWriter(AuditWriter writer) {
        // 2) Dann erst ruft Spring die @Autowired-Methoden auf
        System.out.println("2) @Autowired method");
    }
}

Wenn Sie den Kontext starten und diesen Bean anfordern, sehen Sie genau diese Reihenfolge. Die wichtigste praktische Konsequenz: Method/Setter-Injection ist keine Möglichkeit, „träge später“ eine Abhängigkeit während des Programmlaufs einzufügen. Es ist immer noch Teil des Bean-Bauprozesses. Der Unterschied ist, dass der Bau zweistufig geworden ist: zuerst „erzeugen“, dann „fertigbauen“.

Und noch eine wichtige Konsequenz: Innerhalb des Spring-Containers sollten andere Beans kein „halbfertiges“ Objekt sehen. Der Container versucht, einen Bean nicht nach außen zu geben, bevor er die Injektion abgeschlossen hat. Aber wenn Sie irgendwo ein Objekt manuell erstellen (new) oder Methoden vor Abschluss der Konfiguration aufrufen, kann der Container Sie nicht retten. Daher lieben Setter/Method-Injection Disziplin und mögen kein „lassen Sie uns mitten in der Anwendung die Abhängigkeit ändern“.

5. Anwendung in ContextFlow ohne Schaden für Services

Wenn wir ContextFlow als saubere Spring-Anwendung aufbauen, sollte der Servicelayer (OrderPlacementService, AuditService, ReportingService usw.) maximal glatt sein: Klasse öffnen – Konstruktor sehen – Abhängigkeiten verstehen. Setter/Method-Injection setzen wir punktuell ein, dort wo es wirklich wie eine „Konfiguration“ oder „Anschließen eines Hilfsmoduls“ aussieht, nicht wie ein lebenswichtiger Teil des Szenarios.

Hier ist es wichtig, einen Helper mit Override-Konfiguration von einem Objekt zu unterscheiden, das wirklich auf Post-Construction angewiesen ist. Unten nehmen wir ReportPrinter in der zweiten, strengeren Variante: ohne Fallback-Formatter, daher muss ein solches Objekt außerhalb des Containers manuell konfiguriert werden.

Nehmen wir ein realistisches Beispiel: Wir haben eine Berichtsformatierung über ReportFormatter und möchten separat eine kleine Komponente haben, die einfach den Bericht „druckt“ (in die Konsole oder woanders). Im Lernprojekt kann dies ein infrastruktureller Helper sein, der nicht super streng im Stil „nur über Konstruktor“ sein muss, aber dennoch vorhersagbar sein sollte.

Zuerst – das Interface des Formatierers (kurz, ohne unnötige Details):

public interface ReportFormatter {
    // Vertrag einfach: Eingabe roher Text, Ausgabe formatierte Zeichenkette
    String format(String raw);
}

Dann – eine einfache Implementierung:

import org.springframework.stereotype.Component;

@Component
public class TextReportFormatter implements ReportFormatter {

    @Override
    public String format(String raw) {
        // Textblock verbessert die Lesbarkeit mehrzeiliger Vorlagen
        return """
               [TEXT]
               %s""".formatted(raw);
    }
}

Jetzt – unser ReportPrinter, der den Formatierer per Setter-Injection erhält. Beachten Sie die Idee: Der ReportPrinter selbst kann als „dünne Hülle“ betrachtet werden. Er muss nicht die Hälfte der Domäne in den Konstruktor ziehen, aber verständlich sein:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class ReportPrinter {
    // Wichtig zu merken: das Feld wird nach dem Konstruktor gesetzt
    private ReportFormatter formatter;

    @Autowired
    public void setFormatter(ReportFormatter formatter) {
        // Der Container 'baut' das Objekt in diesem Schritt fertig
        this.formatter = formatter;
    }

    public void print(String raw) {
        // Erwartet wird, dass die Methode im Spring-Kontext aufgerufen wird, wo formatter bereits injiziert ist
        System.out.println(formatter.format(raw));
    }
}

Ja, hier ist formatter nicht final. Das ist ein Kompromiss. Und das ist in Ordnung, gerade weil ReportPrinter ein Infrastrukturdetail ist, kein zentraler Use-Case-Service. Wenn ReportPrinter jedoch für ein Geschäftsszenario kritisch wäre, würden wir zum Konstruktor zurückkehren.

Jetzt zeigen wir, wo Method-Injection sogar „ehrlicher“ im Sinne der Bedeutung sein kann als ein Setter. Angenommen, ScenarioRunner ist eine Klasse, die wir in der Konfiguration erstellen (das macht man oft für „Einstiegspunkte von Szenarien“), und sie kann eine zusätzliche Konfiguration haben: z.B. einen ReportPrinter für die Demoausgabe anschließen.

import org.springframework.beans.factory.annotation.Autowired;

public class ScenarioRunner {

    // Die Abhängigkeit kommt als separater Konfigurationsschritt nach der Objekterstellung
    private ReportPrinter reportPrinter;

    @Autowired
    public void enableReportPrinting(ReportPrinter reportPrinter) {
        // Hier gibt es keinen versteckten Fallback: außerhalb des Containers muss diese Methode manuell aufgerufen werden
        this.reportPrinter = reportPrinter;
    }
}

Hier sind zwei Punkte wichtig. Erstens: Die Methode heißt enableReportPrinting(...), nicht setReportPrinter(...), und das ist beabsichtigt: Wir zeigen einen „Konfigurationsschritt“, keine „Eigenschaftsänderung irgendwo“. Zweitens: Es gibt keinen versteckten Fallback: Wenn Sie ScenarioRunner manuell erstellen, muss die Konfigurationsmethode ebenfalls manuell aufgerufen werden. Das ist der ehrliche Preis für Setter/Method-Injection – das Objekt wird nicht von selbst funktionsfähig.

Wenn Sie dieses Beispiel noch mehr „im Rahmen des Kurses“ gestalten möchten, können Sie ScenarioRunner über @Bean zusammenbauen und die Method-Injection im Inneren belassen. Zum Beispiel:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ScenarioConfig {

    @Bean
    public ScenarioRunner scenarioRunner() {
        // Bean wird manuell erstellt, aber Abhängigkeiten können dennoch über @Autowired-Methoden injiziert werden
        return new ScenarioRunner();
    }
}

Genau so wird der Gedanke gut sichtbar: Die Art der Bean-Registrierung (@Component oder @Bean) hebt nicht auf, dass Abhängigkeiten an verschiedenen Stellen injiziert werden können. Aber ein bloßes new ScenarioRunner() reicht nicht – der Container muss das Objekt anschließend über enableReportPrinting(...) fertigbauen.

Aus praktischer Sicht lautet das Fazit für das Projekt: Constructor-Injection bleibt die Norm für alles, was wie ein „Use-Case-Service“ aussieht und ohne das ein Geschäftsszenario nicht stattfindet. Setter/Method-Injection behalten wir für kleine Infrastrukturobjekte, Adapter, „Drucker“ und Fälle, in denen die Konfiguration wirklich in einem separaten Schritt erfolgt und das Verständnis der Klasse nicht beeinträchtigt.

6. Typische Fehler bei Setter/Method-Injection

Setter/Method-Injection kann man leicht „automatisch“ verwenden, besonders wenn man weniger Code schreiben möchte. Aber dieses Werkzeug hat einige typische Fallstricke, die ein Anfänger fast garantiert erwischt – ungefähr wie NullPointerException, nur kreativer. Im Folgenden sind Fehler, die besonders häufig in Lernprojekten und im echten Code von Anfängerteams vorkommen.

Fehler Nr.1: Verschieben obligatorischer Abhängigkeiten aus dem Konstruktor in einen Setter, weil es kürzer ist.
Dies ist die gefährlichste Stilverschlechterung. Infolgedessen verliert die Klasse einen lesbaren Vertrag, und das Objekt kann in einem nicht funktionsfähigen Zustand erstellt werden. Im Servicelayer wird der Code fast immer zu einem Puzzle „finde die Abhängigkeiten in der gesamten Datei“. Wenn eine Abhängigkeit für die Ausführung des Szenarios obligatorisch ist – gehört sie in den Konstruktor.

Fehler Nr.2: Fehlender Schutz vor dem Zustand „nicht vollständig konfiguriert“.
Wenn ein Feld über Setter/Method-Injection befüllt wird, ist es bis zum Zeitpunkt der Injektion fast unvermeidlich null. Wenn Ihre Klasse manuell erstellt werden kann (was in Lernprojekten ständig vorkommt), kann bereits der erste Aufruf einer Geschäftsmethode zu einem NullPointerException führen. Entweder geben Sie einen Standardwert an, wo dies sinnvoll ist, oder Sie führen eine explizite Prüfung auf korrekten Zustand durch (und scheuen sich nicht, mit einer verständlichen Fehlermeldung abzustürzen).

Fehler Nr.3: Öffentliche Setter-Methoden als Teil der „echten API“ der Klasse.
Wenn die Methode setXxx(...) öffentlich ist, kann jeder Code sie aufrufen und die Abhängigkeit zur Laufzeit ändern. Das verwandelt Ihr Objekt in ein „lebendiges Wesen mit veränderlichen Organen“, und das Debuggen macht sehr viel Spaß (im schlechten Sinne). Für Konfigurationsmethoden ist es besser, die Sichtbarkeit zumindest einzuschränken (z.B. package-private) und Namen zu wählen, die auf eine einmalige Konfiguration hinweisen, nicht auf regelmäßige Änderungen.

Fehler Nr.4: Logik und Seiteneffekte innerhalb der @Autowired-Methode.
Es ist sehr verlockend: „da die Methode sowieso beim Start aufgerufen wird, lassen Sie uns dort die Hälfte der Arbeit erledigen“. So leicht versteckt man wichtige Aktionen an einer nicht offensichtlichen Stelle. Idealerweise macht eine @Autowired-Methode etwas Einfaches: Sie speichert Verweise auf Abhängigkeiten und führt maximal eine leichte Feldkonfiguration durch. Wenn Sie in einer solchen Methode komplexe Logik, Schleifen oder Arbeit mit der Außenwelt sehen – ist das fast immer ein Zeichen, dass Sie „Injektion“ mit „Initialisierung“ verwechselt haben.

Fehler Nr.5: Vermischung von allem ohne einheitlichen Stil.
Wenn in einer Klasse ein Teil der Abhängigkeiten über den Konstruktor, ein Teil über Felder, ein Teil über Setter und noch ein Teil über eine beliebige configure(...) erfolgt, wird das Lesen der Klasse zu einer Quest. Im Rahmen unseres Kurses lautet die Regel einfach: Service Layer halten wir auf Constructor-Injection, Setter/Method-Injection verwenden wir punktuell und bewusst für unterstützende Fälle. Dann liest sich das Projekt vorhersagbar, selbst für einen Anfänger, der den Code zum ersten Mal in seinem Leben öffnet (also für fast jeden von uns am ersten Arbeitstag).

1
Aufgabe
Spring Core, Level 7, Lektion 2
Gesperrt
Formatter über Setter-Injektion
Formatter über Setter-Injektion
1
Aufgabe
Spring Core, Level 7, Lektion 2
Gesperrt
Konfiguration über eine normale Methode
Konfiguration über eine normale Methode
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION