Récemment, j'ai décidé d'essayer le printemps 5 avec projectreactor.io (io.projectreactor: 3.1.1).
Quelqu'un sait-il quel est le meilleur cas d'utilisation de ces fonctions? Quels inconvénients et avantages à utiliser chacun d'eux et où les utiliser?
De bons exemples seront utiles.
Vous avez ici deux catégories d'opérateurs très différentes:
Flux
lui-mêmetransform
et compose
sont pour la mutualisation de codeLorsque vous composez régulièrement des chaînes d'opérateurs et que vous avez des modèles d'utilisation d'opérateurs communs dans votre application, vous pouvez mutualiser ce code ou lui donner un nom plus descriptif en utilisant compose
et transform
.
La différence entre les deux est lorsque les opérateurs mutualisés sont appliqués: transform
les applique à l'instanciation, tandis que compose
s'applique les souscrire (permettant un choix dynamique des opérateurs ajoutés).
Jetez un œil à la documentation de référence pour plus de détails et d'exemples.
as
Il s'agit d'un raccourci pratique pour appliquer un Function
à l'ensemble Flux
tout en conservant le code entier dans un style fluide. Un exemple serait de convertir en Mono
(comme indiqué dans le javadoc), mais cela peut également aider avec les opérateurs externes qui sont implémentés dans un style de méthode d'usine.
Prenez reactor-addons
MathFlux
par exemple, et comparez:
MathFlux.sumInt(Flux.range(1, 10)
.map(i -> i + 2)
.map(i -> i * 10))
.map(isum -> "sum=" + isum);
À:
Flux.range(1, 10)
.map(i -> i + 2)
.map(i -> i * 10)
.as(MathFlux::sumInt)
.map(isum -> "sum=" + isum)
(cela peut vous aider à faire face au fait que, contrairement à Kotlin, Java n'a pas de méthodes d'extension :))
Flux
map
concerne les données. Il applique une fonction de transformation 1-1 à chaque élément de la source, à mesure qu'ils deviennent disponibles.
Dans l'exemple MathFlux ci-dessus, map
est utilisé successivement pour ajouter 2 à chaque entier d'origine, puis à nouveau pour multiplier chaque nombre de la séquence par 10, puis une troisième fois à la fin pour produire un String
sur chaque somme.
J'ai trouvé l'exemple dans documentation de référence peu difficile à suivre
J'ai donc fait les programmes ci-dessous pour envelopper ma tête autour du concept tranform vs compose.
fnstatefull = flux -> {
Flux<String> f = flux.filter(color -> {
//only reds are allowed
return color.equalsIgnoreCase("red");
});
//applies mapping 'toUpperCase' based on the external control 'toUpper'
if(toUpper) {
f= f.map(String::toUpperCase);
}
return f;
};
Transformer
L'opérateur est appliqué au moment de instanciation du flux.
fnstatefull se comportera de la même manière pour les deux abonnés ci-dessous.
Flux<String> f = Flux.just("red", "green", "blue");
toUpper = false;
f = f.transform(fnstatefull);
toUpper = true;
f.subscribe(op -> log.error("ONE>>>" + op));
toUpper = false;
f.subscribe(op -> log.error("TWO>>>" + op));
Production
ReactordemoApplication - ONE>>>red
ReactordemoApplication - TWO>>>red
Composer
L'opérateur est appliqué lors de abonnement au flux.
fnstatefull se comportera différemment pour chaque abonné ci-dessous.
Flux<String> f = Flux.just("red", "green", "blue");
toUpper = false;
f = f.compose(fnstatefull);
toUpper = true;
f.subscribe(op -> log.error("ONE>>>" + op));
toUpper = false;
f.subscribe(op -> log.error("TWO>>>" + op));
Production
ReactordemoApplication - ONE>>>RED
ReactordemoApplication - TWO>>>red