[JAVA] [Für Anfänger] DI ~ Die Grundlagen von DI und DI im Frühjahr ~

Einführung

DI ist eine Abkürzung für Dependency Injection und wird im Japanischen häufig als "Dependency Injection" übersetzt.

Als ich als neuer Absolvent zum ersten Mal von diesem Konzept erfuhr, kam mir das Hatena-Zeichen in den Sinn. Der Zusammenhang mit dem Konzept von DI, DI-Container und Anmerkungen im Frühjahr kam mir nicht in den Sinn.

Dieses Mal möchte ich als Anfänger das Konzept von DI und DI im Frühjahr kurz zusammenfassen und es auf meine eigene Weise organisieren.

Was ist Abhängigkeit?

Ich denke, es ist einfacher zu verstehen, was eine Abhängigkeit im Quellcode ist.

Main.java


public class Main {
    public int hoge() {
        var sub = new Sub();
        return sub.calculate();
    }
}

In der hoge-Methode der Main-Klasse wird eine Instanz der Sub-Klasse erstellt und verwendet. Wenn es eine solche Hauptklasse gibt, wird sie als "Hauptklasse hängt von Unterklasse ab" ausgedrückt.

Ich denke, es ist relativ einfach, Abhängigkeiten zu verstehen.

Was ist Injektion?

Im vorherigen Beispiel wurde eine Instanz der Sub-Klasse intern erstellt. Eine externe Instanz zu erstellen und an die Klasse zu übergeben, die sie verwendet, wird als Injection bezeichnet.

Hier wird ein Beispiel mit einem Konstruktor (Konstruktorinjektion) gezeigt.

Main.java


public class Main {
    
    private Sub sub;
    
    public int hoge() {
        return sub.calculate();
    }
    
    //Konstruktorinjektion
    public Main(Sub sub) {
        this.sub = sub;
    }
}

Früher haben wir eine Instanz der Sub-Klasse in der hoge-Methode erstellt, aber in diesem Beispiel wird die Instanz vom Konstruktor empfangen.

Wenn Sie auf diese Weise tatsächlich die Hauptklasse verwenden,

var sub = new Sub();
var main = new Main(sub);

In Form von wird die Instanz der Unterklasse von außerhalb der Hauptklasse übergeben.

Die Vorteile davon werden später beschrieben.

Was ist ein DI-Container?

Wenn Sie das Wort Container hören, können Sie es in der heutigen Zeit als Docker betrachten, aber der Container im DI-Container unterscheidet sich von dem Container, der im Kontext von Docker usw. verwendet wird.

Wenn Sie es ohne Angst vor Missverständnissen in einem Wort schreiben, fungiert der DI-Container als "Container, der die injizierende Instanz verwaltet".

Wenn Sie versuchen, die Hauptklasse zu verwenden, ohne den DI-Container wie zuvor zu verwenden, benötigen Sie bei jeder Verwendung eine Instanz der Unterklasse.

Wenn Sie einen DI-Container verwenden, wird diese Instanz verwaltet, sodass Sie nicht jedes Mal eine Instanz erstellen müssen.

DI-Behälter im Frühjahr

In Spring können Sie durch Angabe einer Klasse mit einer Anmerkung eine Instanz dieser Klasse als Ziel angeben, das vom DI-Container verwaltet werden soll.

Insbesondere die folgenden Anmerkungen.

Die vom DI-Container verwaltete Instanz kann übrigens mithilfe der getBean-Methode der ApplicationContext-Klasse abgerufen werden.

In Spring können Sie auch festlegen, wie lange der DI-Container die Instanz verwaltet.

Der Bereich kann wie folgt festgelegt werden, und die Bereichsanmerkung wird beim Festlegen verwendet.

Die Standardeinstellung von Spring ist Singleton. Durch Ändern der Einstellung ist es jedoch möglich, die vom Container verwaltete Instanz zu zerstören und neu zu konfigurieren, z. B. in Sitzungseinheiten.

Eine Sache, die Anfänger tun, ist, der Klasse ein Feld zu geben, das sich trotz des Singleton ändern kann. Ein Beispiel ist unten gezeigt.

hogeService


@Service
public class hogeService {
    
    private String result;
    
    public int fuga(String suffix) {
        result = "test" + suffix;        
        return result;
    }
}

Da die Service-Annotation zu hogeService hinzugefügt wird und der Bereich nicht speziell festgelegt ist, ist der Bereich Singleton.

Infolgedessen besteht das Risiko, dass Sie das Ergebnisfeld in einer anderen Sitzung ändern, wodurch es nicht mit dem Gewinde versehen ist.

Indem Sie es wie unten gezeigt zu einer Variablen anstelle eines Klassenfelds machen, wird es zu einer thread-sicheren Implementierung.

hogeService


@Service
public class hogeService {
    
    public int fuga(String suffix) {
        String result = "test" + suffix;        
        return result;
    }
}

DI im Frühjahr

Im Frühjahr können Sie mithilfe der Annotation Autowired DI erstellen.

Es gibt die folgenden drei Injektionsmethoden, einschließlich der zuvor erwähnten Konstruktorinjektion.

Insbesondere ist jeder so.

Main.java


public class Main {
    
    //Feldinjektion
    @Autowired
    private Sub sub;
    
    public int hoge() {
        return sub.calculate();
    }
}

Main.java


public class Main {
    
    private Sub sub;
    
    public int hoge() {
        return sub.calculate();
    }
    
    //Setter-Injektion
    @Autowired
    public setSub(Sub sub) {
        this.sub = sub;
    }
}

Main.java


public class Main {
    
    private Sub sub;
    
    public int hoge() {
        return sub.calculate();
    }
    
    //Konstruktorinjektion
    @Autowired
    public Main(Sub sub) {
        this.sub = sub;
    }
}

Durch Hinzufügen der Autowired-Annotation werden Instanzen aus dem DI-Container in die Argumente von Feldern, Methoden und Konstruktoren eingefügt.

Wenn ich mich selbst injiziere, schreibe ich es übrigens mit der Annotation RequiredArgsConstructor von Lombok in der Bibliothek, wie im Artikel hier beschrieben.

Vorteile von DI

Ein allgemeiner Vorteil ist, dass es einfacher ist, Komponententests zu schreiben. Ich denke das ist wahr.

Hier ist noch einmal das Beispiel am Anfang.

Main.java


public class Main {
    public int hoge() {
        var sub = new Sub();
        return sub.calculate();
    }
}

Wenn die Berechnungsmethode dieser Unterklasse für den Zugriff auf die Datenbank erforderlich wäre, wäre der Komponententest der Hauptklasse sehr schwierig.

Es kann jedoch getestet werden, indem die von DI injizierten Instanzen verspottet werden. Übrigens benutze ich Mockito, wenn ich einen Mock benutze.

Zusammenfassung

Im Folgenden finden Sie eine Zusammenfassung der DI- und DI-Container in einem Wort.

DI: Übergeben einer Instanz einer Klasse, die von einer Klasse von außen abhängt DI-Container: Ein Container, der die zu injizierende Instanz verwaltet

Die Verwendung dieser hat den Vorteil, dass das Schreiben von Tests und das Verwalten des Bereichs einfacher ist.

Das ist alles für den Inhalt. Wir hoffen, Sie finden diesen Artikel hilfreich. Danke, dass Sie bis zum Ende für mich gelesen haben.

Verweise

Offizielle Dokumentation Core Technologies

Recommended Posts

[Für Anfänger] DI ~ Die Grundlagen von DI und DI im Frühjahr ~
[Für Anfänger] Verstehen Sie schnell die Grundlagen von Java 8 Lambda
[Für Anfänger] Erläuterung von Klassen, Instanzen und Statik in Java
Die Frühjahrsvalidierung war in der Reihenfolge von Form und BindingResult wichtig
Memo der JSUG-Studiengruppe 2018 Teil 2 - Bemühungen um Arbeitsspezifikationen im Frühjahr und in der API-Ära
Stellen Sie die Anzahl der Sekunden für den schnellen Vor- und Rücklauf in ExoPlayer ein
[Einführung in Ruby] Über die Rolle von true und break in der while-Anweisung
[Rails] Artikel für Anfänger, um den Fluss von form_with zu organisieren und zu verstehen
Vergleichen Sie die Geschwindigkeit der for-Anweisung und der erweiterten for-Anweisung.
Was sind die Vorteile von DI und Thymeleaf?
[Einführung in Java] Grundlagen der Java-Arithmetik (für Anfänger)
Über DI des Frühlings ①
Über DI des Frühlings ②
Frühlingsgrundlagen ~ DI Edition ~
Geben Sie die statische Ressourcencodierung in Spring Boot an
Bis zur Verwendung von Spring Data und JPA Part 2
Bis zur Verwendung von Spring Data und JPA Part 1
Ich habe die Typen und Grundlagen von Java-Ausnahmen zusammengefasst
Java Häufig verwendete Anweisungsliste (für Anfänger und Anfänger)
[Ruby] Klassenverschachtelung, Vererbung und die Grundlagen des Selbst
Überprüfen Sie das Verhalten von getOne-, findById- und Abfragemethoden mit Spring Boot + Spring Data JPA
Docker-Überwachung - Erläuterung der Grundlagen der Grundlagen
Ich habe versucht, die Grundlagen von Kotlin und Java zusammenzufassen
Fügen Sie die Datei in die Eigenschaften eines Strings mit Spring XML-Konfiguration ein
Beschleunigen Sie das Testen von Validatoren, für die DI im Spring Boot erforderlich ist
Eine Geschichte voller Grundlagen von Spring Boot (gelöst)
Lassen Sie uns das Betriebsbild (Atmosphäre) des DI-Containers von Spring erfassen
Java-Anfänger fassten das Verhalten von Array und ArrayList kurz zusammen
Spring 5 & Spring Boot 2 Einführung für Anfänger wurde veröffentlicht
Erstellen Sie weitere Registerkarten und Fragmente im Fragment von BottomNavigationView
[Spring Data JPA] Kann die And-Bedingung in der automatisch implementierten Löschmethode verwendet werden?
[Für Swift-Anfänger] Ich habe versucht, den chaotischen Layoutzyklus von ViewController und View zusammenzufassen
Verzweigungsverarbeitung mit dem Rückgabewert von RestTemplate und dem Statuscode von ResponseEntity in Spring Boot
Ich werde die Verschachtelung von Aussagen erklären, die Anfänger töten
Grundlagen der bedingten Verzweigung und Rückkehr
Über die Grundlagen der Android-Entwicklung
Spring Boot zum ersten Mal
[Für Anfänger] Zusammenfassung des Java-Konstruktors
Anfänger spielen Janken-Spiele in Java
[Java] Ordnen Sie die Daten des vergangenen Montags und Sonntags der Reihe nach an
Java für Anfänger, Ausdrücke und Operatoren 1
Rufen Sie in Spring Boot eine Proxy-Instanz der Komponente selbst ab
[Für Anfänger] Führen Sie Selenium auf Java aus
Die Grundlagen von SpringBoot + MyBatis + MySQL
[Für Super-Anfänger] Das Mindestwissen, das Sie mit Hashes und Symbolen berücksichtigen möchten
Java für Anfänger, Ausdrücke und Operatoren 2
Betrachten wir die Bedeutung von "Stream" und "Collect" in der Stream-API von Java.
Dies und das von JDK
Erklärung von Ruby on Rails für Anfänger ⑤ ~ Datenbank bearbeiten und löschen ~
[Android Studio] [Für Anfänger] Lassen Sie uns den Bildschirm und das Verzeichnis grob erklären
Formular, das den Wert des sich wiederholenden Elements in Spring MVC erhält
Reihenfolge der Verarbeitung im Programm
Spring AOP zum ersten Mal
[Android] Dynamisch die Höhe von ListView mit Kopie einstellen (für Anfänger)
Klassen und Instanzen Java für Anfänger