ich habe mit Spring Boot bereits erste Erfahrungen gesammelt und sowas wie eine REST basierte API entwickelt. Den Umgang mit Spring Boot finde ich jetzt nicht besonders schwer aber ich verstehe so viele Sachen einfach nicht. Ich habe mir sämtliche Tutorials und auch Bücher zu Spring besorgt und zum Teil durchgelesen was mir bisschen weiterhelfen konnte. Trotzdem gibt es da noch sehr viele Sachen die ich anwenden kann aber ich verstehe nicht warum das überhaupt funktioniert.
Zum Beispiel das Modul Spring Data JPA. Um auf eine Datenbank zugreifen zu können muss man mit dem Modul lediglich eine Entity Klasse und eine Repository Interface erstellen, in der dann die Entität (Domain Klasse) und den Datentyp der ID angegeben wird. Dann kann man durch vordefinierte Methoden auf die Datenbank zugreifen. Schön und gut aber ich raffe einfach nicht wieso man so ein Interface erstellen kann und plötzlich zugriff auf Methoden einer Klasse hat. Wie kann das sein dass man durch ein Interface auf Methoden einer Klasse zugreifen kann? Ich dachte Interfaces geben lediglich vor welche Methoden man implementieren muss. Ja und sonst wie das mit Hibernate und JPA im Hintergrund passiert verstehe ich auch noch nicht so. Die Reference Documentation habe ich mir paar mal angeschaut aber das ist ja eher ein Benutzerhandbuch wie man mit dem Modul umgeht. Ist Spring Data JPA gleichzusetzen mit JPA nur irgendwie speziell für Spring Boot Applikationen angepasst oder ist dessen Implementierung völlig anders?
Also meine Fragen lauten daher: Wie mache ich mich am besten in Spring Boot schlau. Wie komme ich an die Theorie die hinter dem ganzen steckt ran? Welche Ressourcen und Literatur könnt ihr mir empfehlen? Könnt ihr mir sonst Artikel empfehlen die sich mit der Theorie beschäftigen (bitte keine Tutorials).
Bisher war mein Ansatz learning by doing aber ich habe das Gefühl ich habe nur gelernt wie man Aufgaben löst ohne zu verstehen was da wirklich vor sich geht.
Wie es aussieht geht das Spring Framework standardmässig davon aus das die Zielsoftware erweitert werden wird: andere UI, weitere DB-Systeme sollen angesprochen werden, Controller-Methoden sollen (nicht mehr) genutzt werden,... (s.a. https://www.java-forum.org/thema/wi...vernuenftige-klassen-ein.185926/#post-1197005 ) Ob die Erweiterung / Änderung im Einzelfall auch eintritt steht auf einem anderen Blatt. Den Sinn gegen Schnittstellen zu implementieren (s. Openbook - OOP ) erkennt man, wenn eine Änderung / Erweiterung nur an einer (zentralen) Stelle vorgenommen werden muss. Und Frameworks wie z.B. JPA / Hibernate / ... fassen im Hintergrund nur eine (Teil-)Menge an Aktionen / Möglichkeiten mit JDBC zusammen.
Schön und gut aber ich raffe einfach nicht wieso man so ein Interface erstellen kann und plötzlich zugriff auf Methoden einer Klasse hat. Wie kann das sein dass man durch ein Interface auf Methoden einer Klasse zugreifen kann? Ich dachte Interfaces geben lediglich vor welche Methoden man implementieren muss.
Das ist so der code, denn man als "Anfänger" irgendwann schreibt. Der ist nicht falsch, aber er sorgt dafür dass MyClass eine enge Kopplung zu MyRepo hat. Wenn man mal die Implementierung von MyRepo austauschen will, muss man an der Stelle den Typ ändern (sowohl bei der Zuweisung als auch bei der Deklarartion). Und wenn man myRepo in Methoden als Parameter reingibt muss man da auch den Typ ändern.
Man verwendet nur noch das Interface als Definition und muss so nur die Stelle anpassen, wenn man eine andere Implementierung des Interfaces verwenden will. Dennoch hat man zur Compile-Zeit eine harte Abhängigkeit zu MyRepo. Oft will man einfach sagen "Ich möchte eine Implementierung von MyRepoInterface verwenden, aber welche - da möchte ich mich erst zur Laufzeit festlegen". Da kommt die Dependency Injection ins Spiel. Die geht mittlerweile in der Regel über Annotationen, bei Spring Boot ist es @Autowired
Jetzt muss man die Mechanismen noch auslösen, aber wenn der Code läuft passiert folgendes:
* Im Class Path werden alle Implementierungen von MyRepInterface gesucht, die mit einer Annotation markiert sind, dass sie an der Stelle verwendbar (die generischste ist bei Spring Boot @Component). Spring Boot findet dann in der Konstellation genau eine Implementierung - MyRepo, erzeugt diese und weist die der Variablen myRepo zu.
Nun treibt Spring Boot das ganze noch weiter und sagt:
Für bestimmte Interfaces - die Repositories sind da das beste Beispiel - muss im Class Path gar keine Implementierung liegen. Wie die Methoden zu implementieren sind, ist ja klar. Die Komponente mit der DB-Abstrationsschicht (z.B. JPA) analysiert das Interface erzeugt dann dynamisch eine Implementierung die dann der Variablen vom Typ des Repositories zugewiesen wird.
Du kannst mal Spaßeshalber eine Methode ergänzen, mit der JPA nicht umgehen kann - z.B. findByNonExistingAttribut und dann im StackTrace der Exception schauen was Spring Boot da treibt.