We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

Reaktive Programmierung in Java - mehr als eine Erweiterung des Observable-Patterns

00:00

Formal Metadata

Title
Reaktive Programmierung in Java - mehr als eine Erweiterung des Observable-Patterns
Title of Series
Number of Parts
95
Author
License
CC Attribution 4.0 International:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Identifiers
Publisher
Release Date
Language

Content Metadata

Subject Area
Genre
Abstract
Reaktive Programmierung gewinnt ständig an Bedeutung in Zeiten von Mehrkernprozessoren. In Java 9 haben die wichtigsten Interfaces wie Publisher und Subscriber Einzug in die Concurrency Bilbiothek als Flow API gefunden. In diesem Vortrag erläutern wir die Idee hinter der reaktiven Programmierung und schauen uns die zwei bekanntesten Frameworks Spring Reactor und RxJava an, die die Flow API implementieren. Am Ende schließen wir den Vortrag mit der Demo der reaktiven Anwendung auf Basis von Spring 5 und Spring Boot 2 ab.
Keywords
22
Thumbnail
54:22
27
29
36
Thumbnail
1:05:58
38
Thumbnail
1:00:58
65
Thumbnail
44:43
75
91
Thumbnail
1:21:58
94
Java appletOpen sourceFreewareComputer programmingDataflowSpring (hydrology)Demo (music)BootingSoftwareAgent <Informatik>Computing platformWINDOWS <Programm>Computer animationLecture/Conference
Computer programmingJava appletDataflowSpring (hydrology)BootingDemo (music)Functional (mathematics)Lecture/ConferenceComputer animation
Computer programmingDataflowSpring (hydrology)Demo (music)BootingJava appletTOUR <Programm>Series (mathematics)Control engineeringLecture/ConferenceComputer animation
Computer programmingJava appletInterface (computing)CoprocessorSequenceComputer animation
Interface (computing)Computer programmingJava appletCoprocessorPay televisionComputer animation
Pay televisionCoprocessorJava appletComputer programmingDigital photographyPhysical systemExt functorAddress spaceOrder (biology)AuthorizationAuthenticationLetterpress printingComputer-generated imageryDatabaseStructural loadSource codeService (economics)Liste <Informatik>Tor <Netzwerk>IP addressService (economics)Function (mathematics)Tape drivePlug-in (computing)Computer programmingSocial classDataflowComputer animation
Digital photographyAuthenticationAuthorizationData bufferStapeldateiComputer programmingJava appletMiniDiscHard disk drivePhysical systemPoint cloudDigital filterComputer fileTape driveCladeHard disk driveFacebookPoint cloudAuthenticationComputer fileChain ruleWeb serviceDatabaseMetadataForm (programming)Block (periodic table)WEBFunction (mathematics)Service (economics)KommunikationMusical ensembleRollbewegungAuthorizationServer (computing)Stress (mechanics)Object (grammar)Atomic nucleusComputer animation
Computer programmingJava appletRun-time systemWeb browserServer (computing)Client (computing)XML
Computer programmingJava appletSpring (hydrology)InterprozesskommunikationCore dumpVersion <Informatik>FRAMEWORK <Programm>Stack (abstract data type)Direction (geometry)Lecture/ConferenceComputer animationDiagram
Pay televisionStreaming mediaInterface (computing)Computer programmingJava appletCoprocessorType theorySpring (hydrology)FluxPointer (computer programming)Operator (mathematics)Product (business)Digital photographyString (computer science)Error messageMono-FrameworkSet (mathematics)Object (grammar)Direction (geometry)DatabaseData typeEvent horizonMatroidYouTubeWindows RegistryCHART <Programm>State of matterAuszahlung <Spieltheorie>Computer animation
Digital photographyProduct (business)String (computer science)FluxError messageComputer programmingJava appletSpring (hydrology)Event horizonPay televisionFunction (mathematics)Letterpress printingLoginInformationOvalMaxima and minimaPhysical systemDataflowParameter (computer programming)Computer animation
OvalSpring (hydrology)Computer programmingJava appletEvent horizonPay televisionPressureFluxProduct (business)Digital photographyLetterpress printingInformationFunction (mathematics)Operations researchUncertainty principleDigital filterAverageElement (mathematics)Military operationDevice driverSet (mathematics)Computer animation
Letterpress printingComputer programmingJava appletSpring (hydrology)Element (mathematics)Product (business)Digital filterFunction (mathematics)CountingString (computer science)CountingLengthElement (mathematics)Mono-FrameworkSet (mathematics)Product (category theory)MetreComputer animation
Spring (hydrology)Computer programmingJava appletFluxDigital photographyProduct (business)Function (mathematics)Letterpress printingParallelverarbeitungBefehlsprozessorParallel portString (computer science)Maxima and minimaData bufferRing (mathematics)Equals signSoftware testingExpected valueException handlingError messageThread (computing)Data typeTupleElement (mathematics)Tape driveReal-time operating systemMono-FrameworkScheduling (computing)Expect <Programm>Software testingParallelenFlagFRAMEWORK <Programm>Loop (music)Thread (computing)REDUCE <Programm>Error messageServletSingle-precision floating-point formatMilitary operationBlogMatroidVaporProduct (category theory)Atomic nucleusComputer animation
DataflowJava appletSpring (hydrology)Computer programmingSocial classAbstractionExtension (kinesiology)Data typeFluid staticsWeb pageFunction (mathematics)Exception handlingMoment (mathematics)Project <Programm>LeadFunction (mathematics)XML
Java appletComputer programmingSpring (hydrology)Function (mathematics)Exception handlingBootingDemo (music)Mobile appFRAMEWORK <Programm>Musical ensembleComputer animation
Computer programmingJava appletSpring (hydrology)Renewal theoryDatabaseFile viewerGeometrischer KörperHTTPParameter (computer programming)Texture mappingStack (abstract data type)Client (computing)Model View ControllerWEBLecture/ConferenceComputer animation
Computer programmingJava appletInheritance (object-oriented programming)BootingTraffic reportingRevision controlSoftware frameworkSpring (hydrology)Client (computing)Service (economics)BuildingTemplate (C++)DatabaseData modelCore dumpTexture mappingString (computer science)Repository (publishing)Fluid staticsContext awarenessView (database)Beta functionBeer steinGame controllerBuffer solutionElectronic mailing listData typeParsingVariable (mathematics)DatabaseSocial classTable (information)DatabaseDivision (mathematics)Moment (mathematics)Velocity <Framework, Informatik>ForceFlagObject (grammar)MatroidInterface (computing)ZahlRoute of administrationDirection (geometry)Set (mathematics)WEBClient (computing)PostgreSQLKonnektorHTTPSoftware repositoryTemplate (C++)DisintegrationMono-FrameworkFile viewerMongoDBCouchDBData modelVolumenvisualisierungSet (mathematics)FRAMEWORK <Programm>Source codeStructural loadXMLComputer animation
Computer programmingJava appletParsingRoyal NavyMaxima and minimaAsynchronous Transfer ModeSource codeServer (computing)Process (computing)Thread (computing)Structural loadAverageRoute of administrationFRAMEWORK <Programm>Computer animation
Sanitary sewerThread (computing)Structural loadProcess (computing)Source codePersonal digital assistantComputer programmingJava appletMessage passingConcurrency (computer science)Server (computing)Control flowNP-hardEmailStructural loadTape driveThread (computing)Service (economics)Route of administrationFacebookFile viewerDebuggerStack (abstract data type)DatabaseEvent horizonUpdateServer (computing)Direction (geometry)Moment (mathematics)Web pageMultitier architectureStreaming mediaInterface (computing)SpeciesLocal ringComputer animation
User profileEmailMongoDBCodeDatabaseChain ruleSequenceComputing platformFunctional (mathematics)FactorizationAtomic nucleusEmailComputer animationLecture/ConferenceMeeting/Interview
Computer animation
Transcript: German(auto-generated)
Wir sind herzlich willkommen zu unserem Vortrag über die aktuelle Verkündigung im Job. Ich heiße Wadim und arbeite bei der Firma Gerät. Ich heiße Radion und arbeite bei der Firma Gerät.
Bei der Firma Gerät gestalten wir die Gestalten und Bestellung von Software von Fotoprodukten, sei es Abzug, Geposter, Kalender, Fotobücher, Fun-Produkte und weitere Anbieter. Das heißt, wir entscheiden ein Produkt und verbreiten es auf einem anderen Kanal. Das heißt, vor allem im Business- und Dienstbereich aktiv.
Ja, wir sind in Bonn. 2030 gegründet, 2008 eine verständige Fusche gegründet. Da sind ca. 70 Mitarbeiter die Hälfte davon in der RD. Wir sind natürlich auf allen Plattformen mit Kleins unterwegs, im Browser, bei Nokia oder auch desktop, Kleins, Windows oder auch Mac oder auch auf dem Automobilplattform.
Wir sind hier auch Sponsor, deswegen werden wir auch gespannt. Besucht uns gerne, wir lösen auch Preise. Wenn ihr Fragen zum Kontakt habt, sind wir auch kurz danach immer noch da und können diese da antworten. Das ist unser Agent dafür heute. Zuerst sprechen wir über Reaktive, kontrollieren, generieren. Dann sprechen wir über die Reaktiv-Strengths und die Begegnung von Flow-Machinen.
Dann schauen wir uns zwei konkrete Drehpots, die eben diese Reaktiv-Strengths implementieren. Das ist die Java-Inversion zweitens und die Reaktiv-Inversion zweitens. Und am Ende schauen wir ein Thema, eine Reaktiv-Inversion, an, wer die Reaktive-Strengths tun, nicht im Grunde genommen die Reaktive-Strengths. Bevor wir antworten, wollen wir durchfragen,
sind es kein Java-Reaktiv-Strengths. Wer hat schon ein paar Reaktive-Programmierungen? Wir haben auch noch andere Drehpots. Das AK-Left-Left passt auch. Wer hat ein paar funktionale Programmierungen?
Stream-API, Flow-Java-Strengths. Drei oder vier Konzepte sind schon bekannt. Das können wir auch aufbauen. Wir gehen jetzt an meinen Kollegen, ohne da mal zu kregen, und wer beteiligt, hat jeder. Alles klar. Und zwar die Reaktive-Programmierungen.
Ich bin hier. Es ist ein Programm-Programmierprogramm, das sich an Daten und Drehs bringt, in Gründen genommen. Es ist jetzt ein Konzept, das wir schon eine Weile kennen, aus dem Messaging-Bereich. Sei es im Messaging-Design oder Java-Messaging
oder Microsoft, das noch früher war. Oder wenn ich das Ergebnis nicht haben will, dann öffne ich nicht die Methode auf oder die Funktion, sondern melde mich bei einer Nachricht-Publisher
und warte auf das Ergebnis. Das Ergebnis passiert in den meisten Drehpots, in den meisten Kronen. Wenn es fertig ist, bin ich dann gelangweilt. In der Zwischenzeit kann ich etwas anderes machen. Was ist jetzt anders bei der Reaktive-Programmierung? Das Hauptmerkmal bis jetzt geht hier darum, dass wir keine große Netzwerk-Infrastruktur haben,
weil bei Messaging kümmert man davon aus, dass für unterschiedliche Messaging-Systeme dann ein bisschen die Sauber zuständig war, mit der ganzen Maschine oder was man heutzutage im Microservices nimmt. Bei der Reaktive-Programmierung handelt es sich um die Arbeit,
was meist innerhalb einer Anwendung stattfindet. Das heißt, sowohl der Publisher als auch der Subscriber teilen alle eine Anwendung und brauchen dann die meisten Tracks. Was wir auch aus der Messaging-Welt kennen,
es gibt Dutzend von Weisen, um da richtig durch zu gehen, wie man mit Messages arbeitet. So ist es auch in der Java-Welt oder auch nicht in der Java. Das ist zum Beispiel so, dass da mehrere Trainworks entstanden sind, die natürlich miteinander nicht kompatibel sind.
Die sind auch ganz normal nicht kompatibel, weil sie in der Weste und in der Weste unterschiedlich sind, aber man behält sie, und da geht es nur nicht kompatibel. Daher wurde dann eine Initiative gegründet, was dann Reaktive-Systems heißt, wo dann viele Anbieter von der Team, in dem Fall drei wie der X-Java,
die Team, Reaktor und Acker, dann zusammengefunden und dann einteilig von der E-Sweizer auch zu arbeiten. Das Ergebnis davon war dieses Reaktive-Systems-Manifest, was eine spezifische Zone ist, wobei, im Vergleich mit einer spezifischen Zone,
was am Posten ist, es ist sehr gut besichtigt und sehr interessiert, das zu lesen, das ist gut zu verständigen. Das sind dann auch die Struktur-Ebenen, dass eine Reihe von Regelungen genau beschrieben wird, wann und wer genau, wenn und wie es abläuft, und konkret im Falle X-Java,
aber nicht nur im X-Java. Es sind dann auch die Interfaces definiert, die man dann importieren kann, und dadurch sind dann unterschiedliche Applikationen, die reaktiv und mittelwertig einander herausgekommen werden. Kurz später kam dann auch die Org-Community auf Reaktive-Streams zu,
und das Konzept war zu verlocken. Sie haben das einfach komplett unbenommen. Das heißt, die TK9 nimmt sich dann flow-EDI ein, die haben dann die Räume genommen, die in der Basis von Reaktive-Streams und natürlich auch in der Architektur, das heißt in der Regel, die Reaktive-Streams sind einfach unbenommen und über die anderen Packages
nahme ich dann als Teil von TK9. Allerdings, sie haben jetzt einen etwas anderen Deck gegangen. Das heißt, sie haben keine eigenen Equipmenten angeboten. Das heißt, in TK9 existiert zwar flow-EDI, aber keine Equipmenten. Um dann eine Equipmentierung zu haben,
muss man trotzdem eine von Equipmenten benutzen, die dann in TK9 kompatibel sind. Die Equipmenten kennen wir schon aus damals, als XML Framework eingeführt wurde von 19.Java.
Da wurden auch zum Teil Elemente veröffentlicht von XAMN damals, die nicht in die Equipmenten veröffentlicht wurden. Okay, jetzt ist es wie schon gesagt, das ist ein bisschen Chaos jetzt. Jetzt muss man, jetzt gibt es da
objektive developmentative in TK9 Framework, Adapters, oder Converters, was dann jetzt zu Reaktive-Streams, Interfaces oder zu GDK, das alles über TK9-Quartiere macht. Aber es kommt davon aus, dass nach einem Jahr oder so ist dann alles weniger geübt,
und man muss weniger An sich ist API sehr unbesichtlich. Hier gibt es zwei wichtige Interfaces, einmal ein Publisher und einmal ein Subscriber. Der Publisher ist dann das, was uns die Folgen bereitstellt
und was nützliches macht, und Subscriber wird etwas, das ergeben wir sich nicht. Und wenn wir jetzt den Publisher aufrufen wollen, geht das jetzt nicht wie früher über den Notenaufruf, sondern ich nehme mein Objekt, was Subscriber-Interfaces initiiert, registriere ich beim Publisher
und warte, wenn der Publisher einer von diesen Notenaufrufen aufruft. Das ist ziemlich selbstbeklärend, das heißt, wenn die Nachrichten dann kommen, die kommen dann über den Notenaufruf nacheinander, wenn ich dann einer Nachricht erwarte, kommt dann einer, wenn mehrere, dann mehrere, und im Falle eines Fehler oder im Falle, wenn
keine mehr weiter Nachrichten zu erwarten sind, wird dann von R auf R. Das ist jetzt von Sickles' Diagramm, wenn ein Modalnetz-Urmail einfacher ist als das, was ich erkläre, was ich auch verstehe, ist es, wenn Sie dann von den Massen aus, das Subscriber, registrieren Sie
und warten auf aufrufen, was das enthält, unkompliziert oder von R auf N. Ja, es ist auch, es gibt auch ein weiteres, was auch wichtig ist, in dem Fall ist es Subscription, und es ist auch gelacht, was auch ein großes Schwierig ist, was
Rene Schalke-Einteilungen wieder angeht, weil diese Leute wurden früher sehr unterschiedlich geworden, das sind die Backpressure, und das ist dann, kommt dann zum Einsatz, wenn ein Subscriber weiß, dass er die Nachrichten nicht sehr schnell genug abarbeiten kann, das heißt, er ist einfach langsamer als der Publisher und um das Subscription
kann der Subscriber das steuerliche Nachrichten er erwartet, das heißt, wenn der Publisher zum Beispiel mir Wetterdaten sendet, und ich arbeite sie ab, kann ich sagen, dass ich mir jetzt einen Bericht brauche, ein Jahr kontinuiert werde, dann nach einer weitere habe ich noch eins und so weiter,
dann ist die Reaktion besser, das heißt, ich muss mich dann abonnieren und dann requeste ich x ein Element, erwarte, erwarte, wenn sie dann ankommen, und dann kann ich weiter requesten, wenn ich weiter brauche. Ja, jetzt kommen wir zu
die Theorie, das Chaos habe ich schon erwähnt, hier müssten diese gewöhnlichen Gewöhnungen benutzt werden, dass das Publisher das Interface, was von Flow oder von Active Streams Arbeitsgruppe werden dann in unterschiedlichen Frameworks, sie heißen auch unterschiedlich,
z.B. in Java heißt das Observable oder Flowable, in Splink heißt das Flux oder Mono, aber das muss man sich nicht vermehren lassen, das kann sich dann um den Publisher passen, Publisher Interfaces oder Technik limitiert oder kann dann über Adapter zu einem Publisher konvertiert werden.
Jetzt zeige ich ein kleines Beispiel mit der XJava und gleich sagen, das ist ein sehr einfaches Beispiel, hier habe ich keine Besonderheiten oder keine so gut wie keiner jetzt richtig programmiert spezielle Elemente oder Ticks gezeigt,
sondern ich zeige einfach wie man eine normale Anleitung, was normale, also eine klassisch programmiert, was eine elektrische Programmierung überführt und was man da durchgewöhnen kann. Jetzt vergleichen wir, das haben wir jetzt eine ganz normale Funktion
oder eine Methode, die die Weite schon erwähnt hat, wie als Firma, wie durch Fotos oder die eigenen Fotogrufe vor, die dann stellte die Gruppe ein, das heißt es ist einfach eine Methode, die zum Beispiel in einer Klasse Fotoboot sein könnte, wo es einfach die Fotos liefert, was
das Fotoboot will. In dem Fall liefert sie das als eine Liste, holt die zum Beispiel aus einer Datenbahn, das heißt, sie wird dann aus einer Datenbahn geholt, das Resalz herkommt und in einer Schleife wird diese Liste zurückgegeben. Fotos zum Beispiel, da bekommt man
eine Liste mit Unterdrückung. Während das gleiche reaktiv uns schalten muss, das ist ein gewöhnungsbedürftig, aber im Grunde genommen ist es ziemlich genauso aus. Das heißt, jetzt haben wir keine Methode, sondern einen Publisher, passen wir dann Fotoelemente zurück. Hier haben wir eine Liste, hier haben wir Fotoelemente, weil diese um die nächste Methode mehrmals
erwirken werden kann. Und irgendwie jetzt etwas Spezielles wollen, kein Backbackpressure unterstützen. Das ist auch relativ einfach. Das heißt, wir machen das über eine Methode kreiert, wo dann ein Subscriber, ein kleiner Subscriber, das ist ein
Reiter. Er hat gesagt, der wird es ohne machen.
Hier bekommen wir den Subscriber und dann nutzen wir den Subscriber fast direkt und rufen dann onNext
solange wir noch Elemente haben und wenn wir keine mehr haben, onComplete. Das heißt, die Methoden, die die beiden Reaktivprogrammierer teilnehmen, müssen auf diese Weise umgeschrieben werden. Und die Nutzung ist natürlich auch ebenfalls unterschiedlich. In dem Fall bekommen wir diese Daten. Okay, das ist jetzt schon gar kein Fehler. Natürlich muss hier GetFoto sein. Wir bekommen sie dann nacheinander
und nutzen sie dann. In dem Fall einfach Println. Und in dem Fall müssen wir dann eine Funktion übergeben, wiederum gewöhnungsbedürftig, wenn man noch mit Java acht funktionelle Programmierungen noch nicht vertraut ist. Dann entsprechend eine Funktion,
was daraus was macht und den Subscriber übergeben. Okay, und die Art und Weise, wie man mit Funktionale, mit Publisher arbeitet, ist sehr dem Konzept ähnlich, was wir schon aus Java acht Streams kennen. Das heißt, wenn wir dann die Elemente
verarbeiten, machen wir das nicht in der Schleife, wie wir das früher gemacht haben, sondern wir nutzen die Funktion und übergeben, wir nutzen dann die zahlreichen Methoden, die uns ein Publisher, in diesem Fall Observable-Klasse bereitstellt. Und übergeben wir dann Funktionen,
die dann die Elemente, die gepublished werden, entsprechend verändert oder was nützliches daraus machen. Zum Beispiel hier filtern wir alle Customers, indem wir dann nur die Erwachsenen daraus filtern. Hier nehmen wir zum Beispiel die Adresse da raus und
über eine mächtige Funktion Flatmap, die Funktion ist auch sehr ähnlich, dem Stream ähnlich. Allerdings muss Flatmap keinen Stream, sondern wiederum einen Publisher zurückliefert. Und in dem Fall wandeln wir dann eine Liste in ein Publisher um, damit es dann mit
Flatmap kompatibel ist. Und jetzt das Beispiel. Wie ich schon erwähnt habe, wir machen Bilderbücher und wenn ich ein Fotobuch bestelle, muss ich die Fotos,
die eigentliche Bilder in dem Fotobuch alle kurz validieren und dem Nutzer Bescheid sagen, ob das, was er bestellt hat, überhaupt Sinn ergibt, ob wir das drucken können. Da gibt es natürlich zahlreiche Kriterien nach der Größe, nach Format, was auch immer.
Müssen wir alles machen. Und jetzt ist es eine kurze Vorgehensweise. Erstmal müssen wir aus dem Fotobuch die IDs holen von Bildern, von Imagefiles. Dann müssen wir die Imagebilder aus der Datenbank oder die Metadaten zu diesen Bilden laden, wie die Größe angeht und woher das Bild kommt,
ob es dann von Facebook geladen werden muss oder von der Festplatte des Nutzers oder von dem Mobiltelefon. Dann müssen wir dann bei uns auf dem Server, auf der Festplatte gucken, ob das Bild wir bereits haben. Das heißt, wurde das Bild schon geladen oder wurden nur Previews und Metadaten übermittelt. Wenn nicht, müssen wir dann die Bilder nochmal nachladen.
Wenn der Nutzer sagt, ich will mein Facebook Album drucken, dann müssen wir dann die Bilder in High Resolution von Facebook laden. Und dann müssen wir all die Bilder, die wir haben, in High Resolution von Facebook laden. Und, dass es alles auch natürlich im Web ist und
ein Web Service aufrufen, wie es sich handelt, müssen wir natürlich den User natürlich davor noch identifizieren und autorisieren, dass er überhaupt das darf, was er will. Wenn wir jetzt die Zeiten dafür nehmen, was das alles kostet, obwohl es nicht allzu viel ist,
bei 100 Images macht es schon sehr viel Aufwand, Datenbankzugriff, Festplattenprüfung und vor allem das Laden von Facebook zum Beispiel, das ist alles Netzwerk, Kommunikation, kostet alles. Das ist ziemlich viel, was wir jetzt nicht als einfach Web Service Aufruf anbieten können, weil dann wartet der User ziemlich lange. Da müssen
wirklich Progress Bars eingebaut werden oder in mehreren Schritten. Das muss das alles gemacht werden. Jetzt schreiben wir das alles in so einem Reaktiv um. Das heißt, wir fangen damit an, dass wir die ID's von dem Fotobuch nicht als Liste haben, sondern als Observable. Das heißt, es ist Observable,
was uns, wenn wir die brauchen, die ID's von den Büchern rausspuckt. Und wir müssen zu jedem Buch die Daten aus SQL-Datenbank laden. Aus SQL-Datenbank einzeln nachzufragen. Jedes einzelne Buch ist natürlich nicht besonders optimal, da wir dafür 100 Selects brauchen. Wir müssen
das gruppieren. Zum Beispiel 10 Stück pro Select. Dafür um die halt so einen Fluss von Integers umzuwandeln, haben wir hier eine eingebaute Funktion in dem Observable, wo wir einfach aus ID's die Gruppen hier 10 Stück erzeugen und dann diese Gruppen, die das Stück dem DAO übergeben
um dann Metadata zu holen. Und wie ihr seht, hier haben wir Metadata, keine Liste von Metadata, sondern schon einer halt so einen Fluss von Metadata schon ohne Gruppen. Das heißt, diese Gruppierung können wir durch FlatMap lösen, dass wir jetzt wieder
einen normalen Stream haben. Dann nutzen wir wiederum ID's, um dann von der Festplatte die Daten zu holen. Das ist auch ein Beispiel von einem Observable, von unserem Publisher, der auch die ID's bekommt und jede ID dann auf der Festplatte guckt, ob das Bild
da ist und wenn nicht da, macht er dann keinen OnNext-Aufruf und wenn da, werden dann die weiter geleitet in unserer Kette von Daten. Jetzt machen wir das gleiche aus der Cloud, von Facebook zum Beispiel oder Instagram. Und jetzt
haben wir dann drei Streams, die erstmal von einander unabhängig sind, was jetzt umständlich ist. Wir müssen jetzt die Daten müssen jetzt zueinander finden. Das heißt, wir haben einen Stream mit Metadata, was aus der SQL-Datenband geladen wurde, einen Stream mit Dateien von der Festplatte und einen Stream
mit Dateien aus der Cloud. Und wie ich schon gesagt habe, ein Publisher hat zahlreiche Methoden, die diese Arbeit uns leicht machen. In diesem Fall mergen wir zwei Streams zusammen. Das heißt, die Disks und die Cloud-Files werden dann zusammen
gemerged. Jetzt haben wir zwei Streams. Dann werden wir eine weitere Funktion an, heißt Join, was ungefähr so funktioniert wie ein Join von SQL. Wo wir dann alle Kombinationen erzeugen, File 1 mit Metadata 1, 2, 3 und so weiter, ergibt wenig Sinn. Dann müssen wir nochmal nachfiltern, dass die
Ideas hier übereinstimmen. 1 zu 1, 2 zu 2. Das las ich auch schnell filtern. Und dann, wenn wir das gefiltert haben, erzeugen wir aus Pairs, wo wir hier einfach Zusammenführung von Metadata und Pictures, unsere Picture-Objekte, die wir validieren können. Und jetzt validieren wir das.
Und was fällt uns? Die Identifizierung. Das ist auch sehr interessant, weil mit dem Einsatz, dass wir die Identifizierung nicht davor machen können, sondern wir können uns leisten, das parallel zu machen. Das heißt, weil all die Publisher, die wir jetzt definiert haben, wenn wir
die definieren, spezifizieren, entsteht noch keine Arbeit. Das heißt, es ist rein deklarativ, was wir auch aus dem Streamkonzept in Java 8 kennen. Die werden dann einfach spezifiziert. Und die eigentliche Arbeit passiert nur, wenn wir Subscribe aufrufen. Deswegen ist hier Reihenfolge
irrelevant. Wir können Authentifizierende Publisher davor definieren können. Danach, das jetzt hat keinen Einfluss. Dann kombinieren wir die zwei Identifizierung und schon validierte Bilder. Und was uns jetzt bleibt, ist, dass alles wieder zurück
in Formen. Das heißt, eine Liste daraus machen, oder einfach die auf irgendeine Weise nutzen. Das heißt, wir müssen dann unsere Publisher subscriben und warten, bis alle Elemente angekommen sind.
Das Java RX bietet uns dafür eine Hilfsklasse, heißt Block in Observable, wo wir sagen können, bitte auf diesen Publisher warten und das, was hier angekommen ist, einfach drüber iterieren. Und das ist jetzt die ganze Logik, was ich gerade
erwähnt habe, jetzt als ein Programm. Man sieht, dass es sehr übersichtlich und wenn wir das nach objektorientierter Art und Weise gemacht hätten, hätten wir hier eine lange Liste von Schleifen, die dann miteinander verschachtelt gewesen
wäre. Es ist jetzt nicht unbedingt einfacher, aber trotzdem, man sieht, das ist relativ einfach und ein weiterer Entwickler, der das debuggen muss, oder weiterentwickeln, kann durchaus eine Chance, das zu verstehen. Aber was noch wichtiger ist, natürlich, wenn wir die Methoden, die hier aufgelistet sind, nacheinander in einem Tret
aufrufen, brauchen wir ungefähr 20 Sekunden. Hier, wenn wir mit Publisher arbeiten, wie ich schon gesagt habe, das funktioniert jetzt deklarativ. Das heißt, alles, was wir deklariert haben, wenn wir das subscriben, funktioniert alles in einer Art Laufzeitumgebung
von reaktivem Programmierung, was in diesem Fall von JavaRx angeboten wird. Und da werden dann Multitraded jetzt nicht umsonst, aber viel einfacher deklarativ eingeführt. Und wenn wir das jetzt aktivieren, braucht das alles eine Sekunde.
durchaus anderswo uns die Arbeit deutlich erleichtert. Wenn ich das vorher erwähnt habe, wenn wir dann ProgressBus brauchen oder sonst was, jetzt nicht mehr. Wir können dann auf dem Client, auf dem Client im Browser mit JavaScript viel weniger zu programmieren, weil wir schon
auf dem Server viel schneller sind. Das ist jetzt mit meinem Beispiel. Ich gebe jetzt meinen Kollegen wieder das Wort zurück. Und wenn noch Fragen gibt, entweder am Ende, wenn wir doch Zeit haben, oder bei uns an Stand, wäre vielleicht
sinnvoll. Ok, wir haben jetzt ein Framework kennengelernt, nämlich RxJava in Version 2, welches Reactive Streams implementiert.
Jetzt schauen wir uns noch ein weiteres Framework an, nämlich von der Firma Pivotal, die für Springentwicklung zuständig ist, nämlich Spring Reactor 3. Dieses Framework existiert schon eigentlich seit 4 Jahren. Die ersten Versuche waren nicht besonders erfolgreich und wurden auch nicht sonderlich in eine ganze Springfamilie integriert. Erst jetzt erlangt
dieses Framework eine große Popularität, weil mit dem Spring Release 5, welches erst jetzt released wird, nachdem Java nun released wird, ist Spring Reactor Core zentraler Bestandteil quasi eines Reactive Stacks. Das heißt, wir können diese ganze Reactive Paradigma mit
Spring Reactor quasi nutzen und auf andere Springdienste, die wir so kennen, auch zugreifen. Interessant ist auch die Zusammenarbeit mit RxTeam, das heißt, hier ist eine gemeinsame Bibliotheke Reactive Streams Commerz entstanden, IPC Style Richtung Neti oder Kafka.
Das heißt, ja, also es ist einiges jetzt zu erwarten, vor allem wenn das quasi in die Springfamilie integriert wurde. Schauen wir nochmal diese Interfaces an. Die werden wir jetzt, wir werden sehen, wie Spring Reactor Core damit arbeitet. Und um Spring Reactor zu verstehen, muss man im Prinzip
zwei Publisher Typen verstehen. Eins ist Flux und Flux ist dafür zuständig, um uneingeschränkt viele Events oder auch Items zu publizieren. Mono ist hingegen dafür zuständig, maximal ein Item zu publizieren. Das ist so ähnlich wie Optional in Java oder Scala, halt maximal ein Element. Das ist natürlich die Frage,
wieso braucht man Mono, denn Mono ist eigentlich nur Submenge von Flux. Wenn wir uns anschauen, das hat eine semantische Gründe. Wenn wir uns Richtung Datenbank programmieren, wenn wir eine Methode haben, GetAllCustomers, da geben wir in der Methode Collection von Customers zurück. Wenn wir aber fragen, GetCustomerByID, geben wir
natürlich kein Collection, was aus einem Element besteht, sondern einfach Customer zurück. Und eben das zu verdeutlichen, was dann als Rückgabe-Tube kommt, so eine Menge von Element oder maximal eins, wird eben diese Mono und Flux unterschieden. Dazu gibt es bei Mono natürlich weniger Methoden. Es gibt keinen Sinn bei Mono die Methode GetLast oder GetFirst anzubieten,
wenn es maximal ein Element ist. Das ist semantisch einfach nicht richtig. Deswegen eben dieser Unterschied. Jetzt schauen wir uns an, wie man überhaupt diese Publisher instanzieren, konventionieren kann. Eine Menge von Methoden gibt es, die wir am meisten brauchen werden, ist zum Beispiel die Methode Just. Bei Flux
können wir WarArcs von Items übergeben, in diesem Falle Produkttitel. Bei Mono ist es entsprechend nur eins, deswegen ist nur eins möglich. Flux kann man auch aus allen Array- oder Collection-artigen Objekten erzeugen, wie zum Beispiel fromIterable, fromArray oder fromStream. Mono hingegen
geht von callable, runnable oder completableFuture. Das ist eine API, die in Java 8 entstanden ist. Es gibt auch andere Methoden, die wir seltener verwenden, zum Beispiel emptyMono oder Flux zu erstellen oder aus Error-Objekten. Es kommt Error-Signal, zum Beispiel keine Verbindung und daraus können wir auch das, was uns bei OnError
geliefert wird, im Prinzip auch initialisieren, werden wir in der Tat etwas seltener brauchen. Alleine wenn wir Publisher haben, geschieht noch nichts. Elemente müssen, es muss einen Subscriber geben, der darauf subscribt und auf die Elemente reagiert, ansonsten gibt es keine Datenfluss. Interface Publisher, wir wissen es, Reactive Streams,
hat nur eine Methode subscribe und eben diese Flux und Mono Publisher implementieren diese subscribe Methode, die gibt es in sehr, sehr vielen Varianten. Also überladen, die einfachste Variante ist die. Wenn auf dem Subscriber onNext aufgerufen wird, das heißt mit jedem Element, dann können
wir mit Lambda sagen, was wir mit diesem Element machen. Das heißt, wir sagen hier mit Lambda einfach, wir geben dieses Element aus und wenn wir das laufen lassen, dann werden wir praktisch alle unsere Elemente hier jeweils sehen. Jetzt ist es interessant, was hinter diesen Kulissen passiert. Es gibt Methode log und
mit der können wir überhaupt anschauen, wie das Ganze zusammen spielt. Das heißt, framework ruft uns subscribe, auf dem Subscriber registriert subscription und requestet dann bei default uneingeschränkt viele Elemente, das heißt alle, die es gibt. Dann werden onNext quasi alle drei aufgerufen und darauf reagieren, indem wir
diese ausgeben, mit SystemOut Printer lehnen. Und bei OnComplete Signal, der kommt immer am Ende, machen wir hier nichts. Es gibt auch andere Methoden, wie ich gesagt habe, es gibt überladene Methoden, die eben noch zwei weitere Parameter haben. Eins ist eine Lambda Expression, was wir bei OnError Signal machen, da können wir auch ausgeben und auch nicht darauf reagieren
und was wir machen, wenn OnComplete Signal kommt. Da können wir so ein Runnable Objekt übergeben. Dass wir es jetzt gesehen haben, es war eine sehr verkürzte Variante, damit wir Subscriber selbst nicht implementieren müssen. Die Möglichkeit besteht jedoch, wir können einen Subscriber selber implementieren. Das wird dann aber bedeuten, dass wir alle vier Methoden
des Subscriber aus Reactive Streams API selbst implementieren müssen. Das heißt, in unserem Beispiel wäre das von Subscription uneingeschränkt viele Elemente hier anzufordern und bei onNext das auszugeben. Auf diese zwei Signale reagieren wir nicht. Jetzt ist es natürlich die Frage, und der Rodion hat auch ein Konzept von Backpressure
genannt. Das heißt, ein Subscriber ist nicht imstande, alle Elemente von Publisher zu verarbeiten. Der Publisher kann schneller publizieren, als der Subscriber das verarbeiten kann. Es besteht die Möglichkeit sozusagen so einen Backpressure zu implementieren. Hier schematisch dargestellt, wir sagen einfach, wir wollen nur direkt zwei Elemente haben. Und bei dem OnNext-Aufruf immer nur
zwei. Also perchenweise. Mehr können wir quasi nicht verarbeiten. Wenn wir dann logen, dann sehen wir, was passiert, wenn wir mit Backpressure immer nur zwei Elemente ausgeben. Anstatt Request uneingeschränkt werden nur zwei Elemente angefordert. Das heißt, es werden die ersten zwei mit OnNext aufgerufen.
In beiden Fällen geben wir die aus. Und dann kommt wieder ein Aufruf Request zwei. Da haben wir leider nur den dritten Element. Das heißt, es wird dann Kalender ausgegeben. Auf diese Art und Weise kann der Subscriber die Volumen, also die Menge selbst kontrollieren und dem Publisher mitteilen, wie viel er auf Antrieb verarbeiten kann. Wenn er fertig
ist, fragt er nach dem nächsten Häppchen. Und am Ende wird unkomplizt Signal kommen. Ich bin fertig. Genauso wie bei XJava oder generell in der funktionalen Welt gibt es einen Haufen Operationen, die man auf so einen Publisher normalerweise machen kann. Rodion hat die gezeigt, die sind so ähnlich auch in Spring Reactor Welt. Und ich wollte
euch schematisch so einige vorstellen, damit ihr überhaupt das Gefühl kriegt, wie das funktioniert. Zum Beispiel Methode Filter. Es gibt die Möglichkeit, Publisher zu filtern, ein Kriterium übergeben. Hier ist es auch ein Lambda Expression. Wir sagen, wir wollen die Elemente beibehalten, also die Product Titles, die mit P anfangen.
Wenn wir dann auf diesen Publisher subscriben, kriegen wir dann nur die ersten zwei Elemente, die eben mit P anfangen. Das Prinzip ist immer das gleiche. Wir kriegen, wenn wir hier filtern, einen anderen Publisher zurück. Das heißt, es ist non-blocking, das Ergebnis ist noch nicht da, deswegen Publisher von String. Es gibt zum Beispiel Methode Count, um zu ermitteln,
wie viele Elemente wir denn überhaupt haben. Und es ist logisch, dass Count nur ein Ergebnis zurückgibt, eben diese Menge, deswegen ist RugabeTube Mono. Nicht Flux, sondern Mono. Ein Ergebnis vom Tube Long, weil die Menge wir messen, wir halten Long. Ergebnis ist hier drei, wir haben drei Elemente.
Es gibt auch Möglichkeit zum Beispiel zu fragen, erfüllen alle Elemente ein Kriterium? Zum Beispiel Länge der Product Titel muss bei allen Elementen größer als fünf sein. Das können wir mit Methode All abfragen, zurückkriegen wir Mono Boolean. Das ist ein Ergebnis, True oder False, deswegen eben Mono vom Tube Boolean. Wenn drauf subscriben, kriegen wir hier
True, weil eben die Länge überall größer als fünf ist. Es gibt eine Methode Map, wo wir eine Funktion in die andere mappen können. In diesem Falle String in Integer, das heißt Product Titel mappen wir zu deren Länge sozusagen, kriegen wir Flux von Integer zurück. Wenn drauf subscriben, kriegen wir sozusagen die Länge
dieser einzelnen Produkt Titel zurück. Jetzt kann ich überspringen. Viel interessanteres Methode ist Zip. Mit Zip ist es möglich, zwei Publisher oder auch mehrere Publisher zu zippen. Was bedeutet zippen? Das erste Element vom ersten Publisher wird gruppiert mit dem ersten Element des
zweiten Publishers und so weiter. Das heißt hier sehen wir diese Elemente dann perchenweise, wenn wir das zippen. Zip gibt Tupel von zwei Elementen zurück. Das sind zwei Elemente von bestimmten Typen, die entsprechen eben unseren Typen und dann geben wir diese aus. Was passiert, wenn ein Publisher zum Beispiel Flux mehr Elemente hat
als das andere? Wir haben diese Elemente beim Zippen rausgeschmissen. Das heißt alles, was sich perchenweise gruppieren lässt, wird auch gruppiert, der Rest wird praxisignoriert. Wann ist der Use Case für sowas? Stellt euch vor, wir haben zwei Microservices. Eins ist für Ermittlung für Produkt Titel zuständig und das andere für die Ermittlung von Produktpreises
zuständig. Die können wir parallel ausführen lassen und sobald die Zippen. Das heißt so ein Objekt erstellen, der Eigenschaften hat, aus diesen zwei und dann in JSON und was auch immer. Also eine praktische Variante mit Zip. Genauso gibt es auch die Möglichkeit, das kennen wir von Stream,
dieses ganze parallel auszuführen. Das heißt nicht auf einem Kern, sondern zum Beispiel mehrere CPUs zu nutzen. Das kennen wir aus Stream-EPI, da gibt es auch Methode parallel. Das läuft aber im Stream viel einfacher. Hier in Spring-Reactor brauchen wir ein bisschen mehr Arbeit zu machen. Wir rufen hier auch tatsächlich parallel nach sozusagen MapReduce-Algorithmus. Hier wird gemapped.
Dann müssen wir aber noch mitteilen, in welchem Scheduler das ausgeführt wird. Im einfachsten Fall sagen wir random Scheduler parallel. Das ist so ein Scheduler, der Single Threaded ist. Es gibt die Möglichkeit mit Executor und Framework von Java auch andere Scheduler zu erzeugen. Und am Ende müssen wir sozusagen Reduce noch manuell durchführen und so
ein Sequential zurückrufen, damit alles wieder zu einem Ergebnis zurückgeführt wird. Das Ergebnis ist selbstverständlich beim Zippen das gleiche wie im Beispiel davor. Es lohnt sich aber zu überprüfen, ob überhaupt Parallel irgendeinen Vorteil bringt, weil die Kosten für MapReduce-Berechnung können diese sequenzielle Abarbeitung einfach überwiegen.
Aber die Möglichkeit an sich ist da. Alle Operationen, die wir uns bis jetzt angeschaut haben, waren alle asynchron, also nicht blockiert. Deswegen haben wir überall RugabeTube, Mono oder Flux gehabt. Das heißt, es gibt noch kein Ergebnis und das wird erst dann darauf subscribt, wenn Ergebnis überhaupt ankommt. Es gibt die Möglichkeit zu blocken.
Wieso ist das eine schlechte Idee, sage ich später. Es geht so, bei Flux gibt es die Möglichkeit toEtherable aufzurufen. Dann kriegt man kein Mono oder Flux zurück, sondern Etherable. Mit toStream kriegt man eben Stream zurück. Bei Mono gibt es die Methode, die einfach so heißt Block, damit wir direkt wissen, wir blockieren. Es lässt sich aber auch
toCompletableFuture umwandeln. Wieso ist das eine schlechte Idee? Wir kennen ja alle diese Frameworks, wie zum Beispiel Servlet API, die basiert auf einem Threadpool-Konzept. Das heißt, ein Request wird in einem Thread verarbeitet. Wenn der Thread blockiert, naja, es ist vielleicht nicht schlimm. Das ist nur ein Thread. Wenn natürlich alle blockiert werden, dann ist das ganz
schlimm. Es funktioniert aber bei Spring Creator ganz anders. Das basiert auf einem Lmax Disruptor oder eine Variante davor. Sagt jemand dem Lmax Disruptor was? Lmax ist so eine Trading-Plattform. Da müssen quasi zig Transaction pro Sekunde ausgeführt werden.
Diese Firma hat so einen Framework veröffentlicht. Mit dem ist es möglich, mit so einem Konzept, das ist ganz einfach dargestellt, RingBuffer, sozusagen Non-Blocking, dass die Producers Daten produzieren und die Konsumers daraus lesen. Konzepte so ähnlich wie Event Loop, wenn ihr Node.js kennt.
Das ist was komplett anderes als Threadpool. Es werden ganz, ganz wenige Threads verwendet. Bei RingBuffer und bei Lmax Disruptor zwei, drei höchstens. Deswegen, wenn wir irgendwo hier eine Blocking-Operation ausführen, dann blocken wir eine der wenigen Threads, die wir haben. Und es kann sein, dass wir einfach die ganze Anwendung auf die Knie bringen.
Deswegen, es ist vielleicht okay, in irgendeinem Test zu blocken, aber in der kompletten, durchreaktiven Anwendung ist es eine ganz, ganz schlechte Idee. Deswegen, hier stehen ein paar Links. Es ist einfach nur interessant zu lesen, wie das implementiert ist. Wie gesagt, ähnlich wie Event Loop. Es gibt auch die Abstraktion, um das Ganze überhaupt
zu testen. Und die Abstraktion heißt quasi Step Verifier. Wir können das Step Verifier erzeugen, indem wir Publisher in diesem Falle Flags übergeben. Und wir können einzelne Schritte verprüfen. Mit Expect Next Matches prüfen wir, kommen diese Elemente so an, wie wir das halt erwarten. Und am Ende kommt hier Komplizsignal. Und mit
Verify können wir prüfen, sind diese Annahmen, die wir in unserem Test aufgeschrieben haben, richtig oder falsch. Es gibt zwei Ergebnisse davon. Wenn es richtig ist, kriegen wir einfach Java 8 Duration-Objekt zurück, welcher sagt, wie lange der Test gelaufen ist. Machen wir irgendeine Fehler, wie zum Beispiel in diesem Falle sagen wir, es gibt nicht hier dieses Expect Next Matches,
Kalender 4 nicht. Und sagen, es kommt jetzt, muss eigentlich ein Komplizsignal kommen, bekommen wir Assertion Error. Und er sagt uns übrigens auch ganz genau, es kommt kein Unkomplizsignal, sondern es muss noch Unnext, Kalender 4 kommen. Das ist sehr praktisch zu testen. Aus einem anderen Grund auch. Es gibt eine Möglichkeit, sozusagen
Delayed Subscription zu machen. Das heißt, wir sagen Publisher publiziert und ich subscribe x später. x Minuten später, x Tage später, wie auch immer. Wenn wir so einen Test selbst implementieren und das bei jedem Bit laufen lassen und da wird 5 Minuten gewartet, bis es subscribt wird, werden unsere Tests ewig laufen lassen.
Step Verifier nutzt in diesem Falle, im Falle von Delayed Subscription ein Konzept von einer virtuellen Uhr. Das heißt, es wird einfach vorgespült, als wäre das in der Echtzeit. Deswegen ist es sehr praktisch eben mit dieser Abstraktion zur Arbeit, die spart uns keine nötigen Wartezeiten, sondern sorgt dafür, dass das Ganze so mehr oder weniger
in Echtzeit abläuft. Das ist im Prinzip praktisch alles, was zur Vorstellung von Spring Reactor Core angeht. Die implementiert immer noch Reactive Stream Interfaces. Das heißt, diese Interfaces, die in GDK No-Flow-App in diesem Java-Util-Concurrence-Flow-Package kopiert sind, implementiert diese nicht, weil das ist eine Abhängigkeit
zu GDK No, welche noch nicht released ist. Generell keine Wille im Moment dieser Abhängigkeit. Es gibt aber Adapter sozusagen von Spring Reactor Publisher zu Java No-Flow Publisher. Wenn einer das will, kann er das gerne nutzen. Vielen Nutzen bringt das nicht. Ich meine, es sind einfach nur Interfaces und Java implementiert diese
nicht, sondern wir müssen eben eine der Bibliotheken nutzen. Noch eine Empfehlung, wann nutzen wir RxJava 2 oder auch Spring Reactor Core 3? David Karnock ist ein ungarischer Forscher. Der ist Project Lead von RxJava 2 und übrigens Committer Reactor 3, hat so einen Tweet gemacht, wo er sagt, wenn
ihr auf Java 6 noch drauf sind, nutzt Java 6 und auch noch Checked Exception von Funktionen verarbeiten wollt, dann nutzt RxJava 2. Ansonsten, wenn er Java 8 nutzt, oder auch später auf Java 9, dann gerne auf Reactor Core 3 basieren. Ansonsten nehmen sich diese Frameworks an sich alleine nicht viel und deswegen
ist es sozusagen eure Wahl. Das ist alles zur Vorstellung des Spring Reactor Cores Framework. Es ist natürlich so, was wir gesehen haben, ist Business Logik. Damit kann man nur gar keine Anwendung schreiben. Es ist viel interessanter, wie kann man so eine komplette reaktive Anwendung rund um Spring Reactor Core schreiben.
Das wird möglich sein mit Spring Release 5 und vor allem auch parallel wird Spring Boot 2 Release. Und jetzt schauen wir uns einfach schematisch, wie so eine Anwendung aussehen kann. So gegeben sind viele Dinge, die wir hier nutzen in der Preview-Phase. Das heißt, die App ändert sich schnell, weil eben noch kein Release von Spring 5 geschehen ist.
Es lohnt sich aber trotzdem einen Blick drauf zu werfen. Ich werde kurz hier so ein bisschen anzeigen und erklären, wenn ihr tatsächlich die Anwendung haben wollt, da sind unsere Daten hier, schreibt mich an und ich schicke die, damit ihr das laufen lasst. Ihr braucht im Prinzip nur MongoDB, das ist ziemlich schnell installiert.
Was in Spring 5 dazu kommt, wir kennen Spring MVC Stack, parallel wird Spring Web Reactive Stack sozusagen ins Leben gerufen. Er basiert auf den gleichen Annotations, die wir alles schon sowieso kennen, wenn wir eine Spring Anwendung schreiben, das heißt Controller, Request Mapping oder auch Rest Controller im Falle von
Spring Boot. Nur parallel zu MVC Teil wird Spring Web Reactive API bereitgestellt, basierend auf Spring Reactor. Parallel zu Sovlet API, wir wissen Sovlet API wurde erstmal Blocking entwickelt. Erst mit Sovlet 3.1 kam die Möglichkeit Non-Blocking zu programmieren, allerdings lässt sich leicht verwechselt, wann wir blockieren und
wann wir nicht blockieren. Zum Beispiel Request Get Parameter ist eine blockierende Operation, weil HTTP Body gelesen wird. Deswegen ist es sehr schwer, damit komplett Non-Blocking zu programmieren. Mit Reaktive HTTP gibt es unterschiedliche Apps, zum Beispiel Reactor IO oder RX-NETI. Deswegen wir können Reaktive client haben
und statt Sovlet Container, der eben zwar mit 3.1 Asynchronität kennt, können wir gerne Neti, Undertow verwenden oder auch Jeti, die bieten komplett Reaktive Web Client dafür. Jetzt schauen wir uns schematisch an, wie so eine Anwendung aussieht. Die Anwendung kann sich, was ich zeige, sehr einfach. Wir haben so eine Customer-Klasse bestehen aus
First Name und Last Name. Mehr gibt es da nicht und das wollen wir in die Datenbank schreiben, auslesen und irgendwo in der View anzeigen. So sieht dann POM XML aus. Das wichtigste ist, dass hier Spring Boot 2.0 Meilenstein Dependency kommt. Und das mit Spring Boot Starter Webflux ist nichts anderes als dieses Reaktive Spring
Teil, was dazu kam, basierend auf Reactor Core 3. Jetzt gehen wir Schicht für Schicht durch und schauen mal, was wir machen, damit es komplett reaktiv ist. Zuerst müssen wir einen Web Client reaktiv instanzieren und das tun wir sozusagen, wir schreiben eine Klasse, die Spring Boot Application Annotation
hat und hier bauen wir einen sozusagen Bean Web Client und wenn wir hier Reactor Client HTTP Connector mit übergeben, dann instanzieren wir Neti. Also Non-Blocking Web Client. Jetzt gehen wir Richtung Datenbank. Wir wissen alle, dass GDBC API eine Blocking API. Daran hat sich bis jetzt auch nichts geändert.
Und obwohl auf diesjährigen Java One Oracle Entwickler gesagt haben, dass frühestens mit Java 10 Reaktive GDBC API zur Verfügung gestellt wird, wissen wir, Java 10 ist im besten Fall in drei Jahren da und die API wird sicherlich auch da nicht vorhanden sein, deswegen können wir eigentlich vergessen. Es gibt die Möglichkeit zum Beispiel Postgres
Reaktive nicht über GDBC API anzusprechen, aber Spring integriert sowas nicht. Reaktive Anwendungen sind vor allem in der Welt da, wo wir NoSQL Datenbanken verwenden. Und da gibt es schon Integrationen zum Beispiel hier Reactive Mongo Template. Vorher gab es einfach Mongo Template, jetzt gibt
Reactive Mongo Template, der eben sozusagen Non-Blocking die Daten Richtung Datenbank schreibt oder auch ausliest. Und hier übergeben wir einfach wie die Tabelle heißen soll. Spring integriert auch andere Reactive Templates für CouchDB und Cassandra. Das heißt da gibt es etwas Wahl und das können wir schon mal nutzen.
Das ist unsere Customer Klasse sozusagen. Das einzige, was wir hier wirklich bräuchten ist die Document Klasse, damit wir das mit der MongoDB Tabelle mappen. Ansonsten keine Annotation, das heißt alle Spalten werden genauso heißen wie die Properties dieser Klasse. So sieht dann Repository aus, wo wir sozusagen die Datenbank ansprechen.
Hier haben wir die Daten, Repository Annotation und diese Reactive Mongo Template, welches wir vorher erzeugt haben, wird hier injectet. Wenn wir sonst Richtung Repository in ganz normalen Anwendung arbeiten, dann wissen wir, RugabeTube ist immer EntityTube, sozusagen Customer. Wenn wir aber Reactive arbeiten, Non-Blocking, ist RugabeTube
immer Mono oder Flux in der Spring Anwendung. Das heißt das zieht sich durch die ganzen Schichten hindurch. Wir arbeiten nicht mit Entity, sondern mit Mono oder Flux von Entity oder Publisher von Entity. Zum Beispiel, wenn wir Find All gegen Datenbank über Template ausführen, kriegen wir natürlich potenziell viele Customers, deswegen RugabeTube Flux Customer.
Wenn wir hier bei First Name fragen und nur bei Find One nur ein Element davon wollen, wissen wir, es ist maximal ein RugabeTube, also maximal ein Customer. Deswegen Mono von Customer. Wenn wir alle Customers löschen wollen, in der normalen Methode, in der blockierenden Welt würden wir aus der Methode Void zurückgeben. Wir haben gelöscht, wir warten nicht zurück
in der nicht blockierenden Anwendung hier mit Reactive Stack Mono von Void. Das ist immer merken, wir arbeiten hier immer mit Publisher, weil zum Beispiel in diesem Falle, wenn wir alle Customers löschen, gehen wir sofort weiter. Wir warten nicht bis uns Datenbank sagt, ich habe gelöscht, sondern es ist RugabeTube erstmal Mono von Void und irgendwann mal
später kommt so, ich bin fertig. Das heißt Reaktiv. Jetzt gehen wir Richtung View oder View Resolver oder auch Renderingstelle. Das gleiche Spiel. Spring integriert eigentlich nur diese Views. Zum Beispiel GSP. Wir wissen ja, Reactive GSP, das klingt schon
komisch. Das wird wohl nie passieren, dass es sowieso ausstirbt. Spring integriert auch FreeMarker, das nutzen wir zum Beispiel bei uns. Es gibt im Moment noch keine Reaktive API dafür, wie auch bei Velocity Templates. Es gibt aber Timelive View Resolver, also Timelive Renderer und
der bietet jetzt in der Preview schon eine Reaktive Schnittstelle, um zu rendern. Hier im Spring sagen wir mit Configuration, Annotation, wir wollen einen View Resolver sozusagen bekannt geben, damit Spring weiß, wer ist eigentlich für View Renderer, also für View Rendering zuständig. In diesem Falle gibt es Timelive und es gibt, wie ihr
seht, Timelive Reactive View Resolver. Sehr interessant ist aber diese Methode, Set Response Max, Junk Size, Bytes. Hier können wir übergeben, wie viele Bytes auf einmal vom View angefragt werden. Das ist Backpressure Konzept. Hier können wir einfach sagen, wieviel Bytes ich anfrage. Das ist höchst unflexibel, das schauen wir uns
jetzt an, wie wir damit anders umgehen können. Wichtig ist jetzt nur noch Controller-Teil. Das heißt, tatsächlich die Daten aus der Repositore holen, zum Beispiel hier Flux von Customers, also fragen hier Repositore, geben wir alle Customers und übergeben das an Model, genauso wie mit MVC Stack arbeiten. Model View Controller, übergeben wir
Attribut und geben dann diese Flux von Customers zurück. Wenn wir hier genau so das machen, das nennt sich Chunk Base, das heißt, so viele Bytes, wie wir quasi beim View Resolver hier deklariert haben, so viele Bytes wird die View auf einmal anfragen. Höchst unflexibel, weil wir an einer Stelle für alle unsere Objekte
mitgeben müssen, wie viele Bytes sozusagen View anfragt. Objekte können unterschiedliche Größe haben und das ist ziemlich unangenehm, wenn zum Beispiel vom letzten Customer nur paar Buchstaben von First Name kommen und dann werden die weiteren angeforderten, zum Beispiel Netzwerfverbindung ist raus und wir sehen irgendwelche korrupte Ergebnisse.
Deswegen gibt es die Möglichkeit, data-driven zu arbeiten. Das heißt, wir werden nicht nach Bytes fragen, sondern nach Anzahl an Entities. Und wenn wir genau so hier einfach aus der Repository Flux von Customers holen, aber in diese Variable das rappen, in Reactive Data Driver Kontext Variable und hier 500 übergeben,
läuft das dann so, dass der View immer 500 Customers anfragt, die dann rendert und dann wieder 500 anfragt und so bis unkompliz Signal kommt. Das ist viel flexibler, weil wir diese Menge pro Methode setzen können. Das heißt, je nachdem, was wir hier machen können, wir sagen, wie viel wir davon brauchen. Das ist schon viel, viel mächtiges und ich glaube data-driven ist viel, viel besser als
chunk-driven. Wie gesagt, wenn wir Flux von Customers hier in diese Variable rappen, wird es alle sozusagen data-driven abgefragt. So sieht View aus mit Timelive. Überhaupt keine Spur in irgendeiner reaktiven Welt. Wir haben unser Objekt in Data Source Variable gesetzt und wir lesen
in Modell und das lesen wir quasi mit First und Last Name aus und das Framework übernimmt dieses Reaktive komplett von uns. Also wir haben damit nichts zu tun. Framework ist selbst dafür zuständig zu wissen, aha, es wird data-driven gearbeitet. Ich frage 500 Customers, wenn ich kein Unkompliz habe, kann ich weitere 500 fragen. Es ist nichts davon da, diese Komplexität bleibt
für uns verborgen. Sieht genauso aus wie bei ganz normalen Anwendungen. Das ist ziemlich angenehm. Es fehlt noch ein Puzzle-Stück. Diese ganze Serialisierung von Jason und zurück, zum Beispiel von Customer zu Jason, Jason zu Customer. Wir machen das mit Spring mit unterschiedlichen Framework, zum Beispiel mit Jackson.
Jackson ist wiederum eine blockierende AP. Das heißt, diese Serialisierung läuft blockierend und bereits 2013 haben die Spring-Entwickler angefragt, wann kommt denn Reaktive AP dazu? Erst im Mai dieses Jahres kam die Antwort, es wird in die nächste Meilenstein-Version integriert, sodass auch diese Jason-Parsing
oder Hin- und Her-Serialisierung, Deserialisierung auch komplett non-blocking funktionieren kann. Es ist jetzt logisch, der Druck kommt, weil Spring 5 erscheint, diese ganze Reaktiv-Stack erscheint und alle diese Frameworks oder auch die Firmen und Community dahinter stehen, die haben jetzt großes Interesse, ihr Produkt auch Reaktiv anzubieten. Ansonsten wird es irgendwie mal weg vom Fenster sein.
Deswegen kommt es immer mehr. Das überspringe ich. Im Prinzip haben wir so durch alle Schichten hindurch jetzt diese Reaktive-Anwendung gesehen. Was ich noch sagen wollte, was sind die Benefits von Reaktive-Applications? Es ist vor allem die effiziente Ressourcenausnutzung. Das heißt, wir können mit wenigen Threads, wir haben insgesamt weniger Threads,
viel, viel mehr abarbeiten. Wenn man ganz normale Anwendungen entwickelt, wisst ihr, wie schwierig das ist, überhaupt Threadposts zu size. Die haben wir überall, halt in der Servlet-Welt, in die Richtung Datenbank ist Thread-Pool-Size. Machen wir Fork-Join-Pool müssen wir Thread-Pool-Size. Und am Ende wissen wir nicht, können wir das, kann ein Server das abarbeiten?
Wir replizieren schnell die Server, damit diese Last überhaupt abgearbeitet wird und uns die Thread-Pools nicht ausgehen. In der Reaktive-Anwendung haben wir generell wenig Threads. Threads blockieren nicht. Das heißt, der Fluss läuft immer weiter. Man kann mit wenigen Threads mehr machen und dadurch auch Server sparen.
Weil alle Threads komplett beschäftigt sind, alle wenige. Was sind die typischen Anwendungen von Reaktive-Applications? Zum Beispiel External Service Calls. Das heißt, irgendwelche Integrationsanwendungen, wo wir halt mit Facebook sprechen, Microservices, die über Netzwerke sprechen. Überall, wo irgendwo IO im Spiel ist und auch Latenz oder zeitliche
Latenz im Spiel ist. Und auch konkurrierende Messages oder auch Streaming-Applikationen. Wir kennen eigentlich selber Reaktive-Applikationen recht gut. Zum Beispiel Facebook. Wenn wir auf deren Seite gehen, sehen wir im Prinzip Nachrichten, die wir publizieren. Ja, mit Werbung, und so weiter. Wenn wir aber nach unten scrollen, werden die Nachrichten automatisch
nachgeladen. Und das ist quasi reaktiv. Das heißt, es sind potenziell unendlich. Und Facebook-Seite erkennt, in welchem Klein sind wir, wieviel Nachrichten oder ja, wieviel Reaktive-Applikations können gleichzeitig angezeigt werden. Und das ist so ein Backpressure. Der fragt genauso viel, wie wir sehen wollen, plus vielleicht ein bisschen mehr als
Pre-Fetching. Und es gibt keinen Button, Next, Page oder so, sondern wir scrollen nach unten und die werden automatisch nachgeladen. Das typische Anwendungsfall von Reaktive-Programmierung mit Backpressure. Ähnlich Kontaktvorschläge von Xync und LinkedIn. Wir scrollen nach unten und es werden uns immer Kontakte angeboten. Sei es die, die bei unserer
Firma arbeiten, die wir noch nicht haben, oder wo wir gemeinsame Freunde haben, sie werden automatisch nachgeladen. Nach dem gleichen Prinzip, wieviel überhaupt auf das Bildschirm passt. Sie können nicht unendlich alle das komplette Datenbank aussaugen, wenn wir ewig nach unten scrollen, sondern genau das, was wir uns anschauen wollen. Auch irgendwelches Updates auf
die, sag ich mal, Fußballergebnisse wäre so ein typischer Beispiel. Wir sehen die Seite und es werden Live-Ergebnisse aktualisiert. Das heißt, praktisch ein unendlicher Stream von Updates wird geschickt. Was sind die Gefahren? Für das falsche Problem werden wir die Sache eigentlich nur noch schlimmer
machen. Zum Beispiel, wenn wir irgendeine Webseite, eine Arztpraxis mit Reaktive-Stack implementieren wollen, dann ist es einfach der falsche Use-Case. Oder wir haben irgendeine Batch-Anwendung, die die Daten aus dem lokalen Storage verarbeitet. Oder auch aus der naheliegenden Datenbank. Die Use-Case ist, wenn wir potenziell uneingeschränkt
viele Events haben und wie auch Latenz dazwischen haben. Im Prinzip das, was ich erwähnt habe, das passt prima. Es ist schwieriger zu debuggen, denn im Prinzip wird die ganze Logik in den Threads ausgeführt, die zum Beispiel Ring-Buffer, also diese Elmax-Disraptor selbst verwalten. Das heißt, kaum wird irgendwas in dem Main-Thread ausgeführt. Das
erschwert natürlich die Debugging. Und das, was wir mehrfach erwähnt haben, wenn wir an irgendeiner Stelle irgendeine blockierende Operation ausführen, es kann sein, dass wir die Anwendung komplett blockieren. Also einen kompletten Server blockieren. Das heißt, wenn reaktiv, dann am besten durch den ganzen Stack hindurch und an keiner Stelle blocken, soweit es geht. Also sonst, wie gesagt,
ich bin selbst gespannt, wie es mit diesem Spring 9, mit dieser reaktiven Paradigma weitergeht. Es muss erstmal Java 9-Release werden, dann wird Spring 5 released. Dann gehe ich mal davon aus, dass sich in einem Jahr alles stabilisiert und alle anderen APIs, die Spring integriert, auch Reaktiv-Schnittstelle anbieten. Also Reaktiv-Schnittstelle. Im Moment ist
Richtung Datenbank einiges. Richtung View haben wir nur Timelift gesehen. Wir wollen Qual der Wahl haben und nicht nur unbedingt auf Timelift setzen. Ich gehe davon aus, dass das schon automatisch kommt. Ansonsten sind unsere Kontaktdaten, wenn ihr, sag ich mal, diese Anwendung haben wollt, damit ihr den Code anschaut, mich gerne anschreiben, ich schicke das. Das ist jetzt, wie gesagt,
ein MongoDB im Voraus. Das ist aber sehr leicht installiert. Man muss nicht mal irgendwelche Kenntnisse von MongoDB haben. Das muss einfach nur gestartet werden. So. Ansonsten bedanke ich mich. Wir sind fertig. Ich glaube rechtzeitig sogar. Wenn ihr noch Fragen habt, gerne.
Wir haben eine Frage zu dem Beispiel der 100 Fotos und dem Observables. Wenn ich das richtig verstanden habe, haben wir dann eine Beschleunigung von Faktor 20 auf einen von 20 Sekunden auf eine Sekunde. Das ist ja der Kern von der reaktiven Programmierung, dass die Funktionale
Ketten haben. Das heißt, wenn ich jetzt hier RxJava und Observables benutze, das ist ja erstmal schneller. Das wird ja erstmal kompakter gestiegen, aber noch nicht schneller, weil RxJava ja erstmal die Folgen wirklich alles auf einem Swap ausführt. Es sei denn, ich habe eine reaktive Plattform oder ich habe eine reaktive Datenbank treibe
oder ähnliches. Oder, wie in dem Reaktor Beispiel, ich weise expressiv scheduler zu. Das habe ich jetzt in dem Beispiel aber auch nicht gesehen. Ich finde die Frage, wo kommt da die Asynchronität bei? Das habe ich übersprungen. Das ist jetzt leichter, die Asynchronität
da einzuführen. Selbstverständlich an den Stellen, wo die Asynchronität ist, müssen wir RxJava dann anweisen, dass das multi-threaded ausgeführt wird.
In dem Fall ist es aber relativ leicht. Dann machen wir einen Funktionsaufruf, wo man gesagt wird, dass wird dann dieses RxJava ausgeführt. Und dann ist von alleine, von der Fahrzeugentwicklung von RxJava dann gesteuert. Aber ja, das ist jetzt
nicht automatisch. Man muss noch ein bisschen dazutun, wenn es sehr groß im Hintergrund auch initialisiert wird. Die Arbeiten. Mir auch gefallen war bei dem Beispiel, dass da im Prinzip zwei Streams geworden sind und alle Permutationen ausmultipliziert. Dann wird das
gefiltert. Das heißt, für Elemente braucht man ein N-Quadrat Zeit. Das ist besonders elegant. Das ist jetzt nicht so schlimm, die Tatsache, dass die Elemente die werden dann nicht gecashed, weil jedes Element, der
erstellt wird, wird das im nächsten Zoll übergeben, in diesem Fall noch hinter, und wird dann sofort... Ja, da haben wir es bestellt. Dann werden alle möglichen Farben aktiviert. Ja, das ist jetzt sehr aktiv. Es lässt sich sehr schwer malen.
Aber die Elemente, die wissen, die werden nicht als Wissen erzeugt. Das heißt, ein paar Elemente werden erzeugt und dann wird sofort, da das alles in die Karantäne funktioniert, das wird erzeugt, und sofort dem nächsten Element in die Kette umgegeben und dann wird es uns stürmen.
Das ist natürlich jetzt eine Auslassung, wenn wir die Kette verlassen auf den Collector. Aber wenn wir eine verschachtete Schleife im Java machen, dann hat sich auch nicht sehr viel anders. Wenn wir das in der Schleife machen, dann wird ja auch sehr viel Gipfelentzelt, so zu sagen.
Aber dann zerspringen sie auch irgendwie sofort und leicht. Das heißt, der Filter ist das Einzige, was die ARP oft optimiert? Nach dem nächsten Aufruf, in diesem Fall in dem Filter, sind dann die Objekte, die gerade erzeugt wurden?
Sonst Fragen? Besucht uns gerne an unserem Stand IP Labs. Sind uns ca. eine Stunde da oder etwas mehr.
Oder gerne auch per Sync anschreiben oder per E-Mail. Vielen Dank nochmal.