Avec cela, je devrais être en mesure de me débarrasser de tout ce qui touche à de l'introspection et donc me rapprocher de la compilation native :D (avec ce maudit Spring Boot que j'ai appris à détester avec le temps).
L'exemple donné
package com.zetcode.routes;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;
import static org.springframework.web.reactive.function.BodyInserters.fromValue;
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
import static org.springframework.web.reactive.function.server.ServerResponse.ok;
@Configuration
public class MyRoutes {
@Bean
RouterFunction<ServerResponse> home() {
return route(GET("/"), request -> ok().body(fromValue("Home page")));
}
@Bean
RouterFunction<ServerResponse> about() {
return route(GET("/about"), request -> ok().body(fromValue("About page")));
}
}
Prérequis
Avoir activé Actuator.
Configuration
Ajouter ceci dans votre fichier bootstrap.yml
server:
shutdown: graceful
Déclenchement de l'arrêt
Envoyer une requête de type POST sur /actuator/shutdown. Par exemple :
curl -X POST localhost:8080/actuator/shutdown
Merci à @Lenny pour le lien.
Une des nombreuses raisons pour lesquelles je préfère éviter l'écosystème Spring Boot le plus possible. Tout étant basé sur le scanne du classpath, rien n'est vérifiable au build et tous les imports sont validés/calculés au runtime.
Bref, avant Spring et Spring Boot nous avions un environnement Java où tout était vérifié à la compilation, fortement typé statiquement et à présent nous avons une sorte de clone verbeux de JavaScript avec des temps de build (ce que JavaScript n'a pas puisque interprété) et des temps de démarrage hyper-longs (ce que JavaScript n'a pas puisque interprété).
Bref si c'était pour transformer Java en JavaScript merci mais non merci.
Sinon Kotlin + Jooby + Ktorm sur JVM ça remplace totalement Java + Spring Boot + Hibernate, c'est plus simple (pas de conflits internes de versions, pas de mécaniques implicites obscurs à connaître), ça prend littéralement 10 fois moins d'espace disque pour faire la même chose et c'est plus rapide (démarrages instantanés, tient plus de 100 fois mieux la charge d'après techempower).
Si vous codez dans un langage à destination d'une JRE (Kotlin, Java, Scala, Groovy, etc) vous avez sûrement entendu parler de Spring Boot. Pour ce qui ne le connaissent pas, c'est LE framework qui est parti de rien (à l'origine c'était seulement Spring Framework), puis qui a grossi tout doucement depuis 15 ans et est devenu aujourd'hui un mastodonte aussi gros, lourd, pénible et lent à démarrer que l'ancien JEE (avec des Websphere et Weblogic, etc).
Mais en réalité est-ce que c'est mal ?
Pas vraiment, Spring Boot pousse à produire du code en couche avec des singletons présents partout à chaque couche. Ce n'est pas comme cela que l'on écrit du code concis, découplé, court et maintenable, mais ça a le mérite de s'écrire vite, d'être simple pour des débutants et de fonctionner quand même (en tout cas au début). Après c'est un enfer à tester en terme d'écriture et de temps d'exécution mais bon, qui teste encore son code en 2021 ? #Sadness
Alors quel est mon problème ?
Mon problème c'est que parmi l'ensemble des développements actuels auxquels je contribue chez mes clients, ceux-ci sont couplés totalement à Spring Boot. Vous montez de version, vos développements risquent de péter, vous souhaitez quitter Spring Boot pour autre chose de plus rapide comme Quarkus, pas possible les libs ont été codées pour Spring Boot, d'ailleurs pour les utiliser aucune lib ne pourra se charger si vous n'avez pas Spring Boot car seul Spring Boot doit être en mesure de les instancier. #Folie
Et c'est ça mon problème, Java avait supprimé la problématique de nettoyage de la mémoire, Spring Framework avait supprimé la problématique de création des instances et Spring Boot supprime aujourd'hui la notion d'architecture (ce qui n'a pas du tout le même impact puisque ça touche à la capacité d'innover et de faire différemment), or un code propre qui soit fonctionnel et objet requiert la création et la destruction permanente d'instances immutables à cycle de vie ultra court (une action puis poubelle), ce qui est l'antithèse même des singletons omniprésents, paramétrés par AOP (ndr. Aspect Oriented Programming) et poussés par Spring...
En synthèse :
Pour toutes ces raisons, Spring Boot va à mon sens à contre courant des meilleures pratiques de développement connues et reconnues à cette heure parce qu'il préserve les façons de coder d'il y a plus de 20 ans et venant de langages ni objets ni fonctionnels comme le C, pire encore les "développeurs Spring Boot" sont tellement à fond dans Spring Boot qu'ils n'arrivent même plus à penser leurs libs comme des éléments qui puissent s'utiliser en dehors de Spring Boot et c'est ce qui me fait dire que Spring Boot est un contre-choix et une fausse-bonne idée.
@Animal : nous en discutions hier soir mais tu peux aussi utiliser le maven-assembly-plugin
pour faire un fatjar, en lui demandant de dézipper les dépendances puis en rezippant le tout (un jar étant un zip dont l'extension est renommée .jar
).
Tout un tas d'exemples en Spring Boot notamment un simple "Hello World!".
Pour toi @animal
Edit : le lien à jour : https://spring.io/projects/spring-cloud
Vous le savez peut-être, je ne suis pas fanna de Spring mais comme tous mes clients l'utilise, il faut bien que je me maintienne à jour.
Ici, le tableau de compatibilité des versions entre Spring Cloud et Spring Boot.
En résumé : Spring Cloud Hoxton s'attend à ce que vous lui tiriez Spring Boot 2.2.x.
Oh je suis surprise... Spring Boot serait aux micro-services ce qu'une Baleine serait aux petits poissons... LOL
Pour info, nous avons viré intégralement toute la stack Spring Boot depuis trois ans :
- Spring Boot => Sparkjava
- Spring DI => Feather-java
- Hibernate => ActiveJDBC
- Jackson => Jsoniter => Jackson de nouveau (à cause d'ActiveJDBC notamment et de ses récentes améliorations de performances)
- JWT => Petite API perso + Bouncy Castle
- Etc.
Résultats :
- Une application qui passe de 45 Mo de JAR à 6,5 Mo sur le disque.
- Un démarrage instantané.
- Une consommation mémoire divisée par 5 !
Mais bon, Spring est à la mode comme l'ancien JEE et comme son ancêtre il finira par s'effondrer sur lui-même à cause de son propre poids.
Via Riduidel.
SpringBoot scanne notre CLASSPATH à la recherche de tous les frameworks connus pour les instancier pour nous (parce que nous sommes sûrement de gros débiles). Aussi, dès qu'il trouve l'existence de Flyway dans votre CLASSPATH , il charge une instance de Flyway dès démarrage de Spring et exécute automatiquement un DB migrate (déjà l'aspect "tu touches à ma base sans me demander mon avis" m'énerve au plus au point mais admettons).
Bref, nous devons dire explicitement à Spring d'exclure Flyway de l'auto-instanciation et donc voici la solution :
@EnableAutoConfiguration(exclude=FlywayAutoConfiguration.class)
Je viens de me rendre compte que tu étais envoyée par Google !
Merci pour tes tutos sur Aurelia et SpringBoot. Cela va m'être très utile.