L'équipe de portage Spring pour GraalVM a récemment publié sa première version majeure, la version bêta native de Spring. En collaboration avec les créateurs de GraalVM, ils ont pu corriger de nombreux bogues à la fois dans le compilateur lui-même et au printemps. Maintenant, le projet a un support officiel, son propre cycle de publication et vous pouvez le sentir.
L'obstacle le plus important lors du portage de code de JVM vers des binaires est le problème de l'utilisation de puces inhérentes uniquement à java - réflexion, travail avec le classpath, chargement dynamique des classes, etc.
Selon la documentation, les principales différences entre une JVM standard et une implémentation native sont les suivantes:
L'analyse statique de l'ensemble de l'application est effectuée au moment de la construction.
Les composants inutilisés sont supprimés lors de l'assemblage.
La réflexion, les ressources et les proxys dynamiques ne peuvent être configurés qu'avec des configurations supplémentaires.
Au moment de la construction, tous les composants sont corrigés dans le Classpath.
Pas de chargement paresseux de la classe: au chargement, tout ce qui vient dans les exécutables sera chargé en mémoire. Par exemple, pour que l'appel à Class.forName ("myClass") fonctionne correctement, vous devez avoir myClass dans le fichier de configuration. Si aucune classe n'est trouvée dans le fichier de configuration qui est demandé pour charger dynamiquement la classe, une ClassNotFoundException sera levée
Une partie du code sera exécutée au moment de la construction pour lier correctement les composants. Par exemple, des tests.
, , , - .
Spring AOT, Graal VM .
Spring AOT native-image.properties
, reflection-config.json
, proxy-config.json
resource-config.json
.
Graal VM , META-INF/native-image
.
, Spring AOT. maven spring-aot-maven-plugin
, gradle - spring-aot-gradle-plugin.
, gradle :
plugins {id 'org.springframework.experimental.aot' version '0.9.0'}
, , .
, , . , .
, WebClient
org.springframework.nativex.hint
, :
@TypeHint(types = Data.class, typeNames = "com.example.webclient.Data$SuperHero")
@SpringBootApplication
public class WebClientApplication {
// ...
}
, Data
, SuperHero
. , .
graavlvm , java.lang.reflect.Proxy
@ProxyHint
.
, , :
@ProxyHint(types = {
org.hibernate.Session.class,
org.springframework.orm.jpa.EntityManagerProxy.class
})
- , @ResourceHint.
, :
@ResourceHint(patterns = "com/mysql/cj/TlsSettings.properties")
/ , @InitializationHint:
@InitializationHint(types = org.h2.util.Bits.class,
initTime = InitializationTime.BUILD)
, @NativeHint
:
@Repeatable(NativeHints.class)
@Retention(RetentionPolicy.RUNTIME)
public @interface NativeHint
, , :
@NativeHint(
trigger = Driver.class,
options = "--enable-all-security-services",
types = @TypeHint(types = {
FailoverConnectionUrl.class,
FailoverDnsSrvConnectionUrl.class,
// ...
}), resources = {
@ResourceHint(patterns = "com/mysql/cj/TlsSettings.properties"),
@ResourceHint(patterns = "com.mysql.cj.LocalizedErrorMessages",
isBundle = true)
})
, , classpath .
Graal VM Spring AOT.
Spring Native , start.spring.io. JPA spring , CRUD . Graal VM , BP_NATIVE_IMAGE_BUILD_ARGUMENTS
Spring AOT, Buildpacks, “<buildArgs>
” pom.xml
, native-image-maven-plugin
.
En fait, nous exécutons les commandes mvn spring-boot: build-image ou gradle bootBuildImage
- et la construction de l'image commencera. Il est à noter que le collecteur a besoin de plus de 7 Go de mémoire, pour que l'assemblage soit terminé avec succès. Sur ma machine, l'assemblage, ainsi que le téléchargement des images, ne prenait pas plus de 5 minutes. Dans le même temps, l'image s'est avérée très compacte, seulement 60 Mo. L'application a démarré en 0,022 seconde! C'est un résultat incroyable. Considérant que de plus en plus d'entreprises passent aux K8 et démarrent une application, ainsi que les ressources utilisées sont très importantes dans le monde moderne, cette technologie permet à Spring de faire du framework numéro un pour tous les types de microservices, même pour les implémentations FaaS, où la vitesse à froid est très importante.