Micronaut für Cloud-native JVM-Microservices

Seite 2: Vorteile gegenüber anderen Frameworks

Inhaltsverzeichnis

Das Micronaut-Framework fokussiert sich auf einige Kriterien, die ihre zunehmende Relevanz in erster Linie durch die Anforderungen an Cloud-Anwendungen gefunden haben. Außerdem legt das Team wert auf eine gute Developer Experience, deren Messlatte sich aufgrund neuer Frameworks, häufig deklarativer Konfiguration und Programmierung auf Basis von Annotationen sowie zunehmend eleganteren APIs, stets erhöht.

Micronaut zielt auf folgende Aspekte von Anwendungen für die JVM ab und versucht, sie zu optimieren:

  • schneller Applikationsstart
  • reduzierter Laufzeit-Speicherbedarf
  • minimaler Einsatz von Java Reflection
  • minimaler Einsatz von Java Proxies
  • einfache, schnelle Applikationstests

Die schnelle Startzeit fällt sowohl bei der Entwicklung, bei der Ausführung von Integrationstests als auch bei einem Kaltstart als AWS-Lambda-Funktion positiv auf. Aufgrund des geringen Speicherbedarfs zur Laufzeit eignet sich Micronaut besonders für die Entwicklung von "Serverless"-Anwendungen. Damit verbunden wirbt das Entwicklungsteam vor allem mit dem inhärenten Cloud-Support, der keine zusätzlichen externen Abhängigkeiten benötigt, sondern Teil des Ökosystems ist.

Mit Micronaut sind die Startdauer von Anwendungen und deren Speicherverbrauch nicht an die Größe der Codebasis gebunden. Die Startdauer einer minimalen Micronaut-Anwendung liegt zurzeit bei etwa einer Sekunde. Mit Micronaut belegen Anwendungen einen Speicherplatz in Bereichen von zehn MBytes statt hunderten, ohne Kompromisse in Bezug auf zeitgemäße Framework-Funktionen eingehen zu müssen.

Bereits zur Kompilierzeit nutzt das Framework die deklarativen Informationen aus Annotationen, um zusätzliche Klassen zur Umsetzung der Funktionen zu generieren und sie zusammen mit dem Anwendungscode zu kompilieren. Proxies und Caches reduziert es entsprechend.

Die geringe Startdauer und der geringe Memory Footprint gelingen durch die Verwendung von Dependency Injection (DI) zur Kompilierzeit und der AOP-API (Aspect-Oriented Programming), die auf die Java Reflection API verzichten. Micronaut verwendet hingegen die Annotation Processor API für Java und Kotlin sowie AST-Transformationen für Groovy zur Kompilierzeit. Reflection-basierte IoC-Frameworks (Inversion of Control) wie Spring untersuchen den Classpath, laden und cachen Reflection-Daten für jedes Feld, jede Methode und jeden Konstruktor. Spring beispielsweise liest den Bytecode jeder Bean, die es zur Laufzeit findet, und erzeugt für sie diverse Metadaten. Das erzeugt Overhead.

Generell ist es bemerkenswert, wie viel Reflection-Logik in typischen Java-Frameworks existiert, obwohl die Sprache Java statisch typisiert ist. Während Prüfmechanismen zur Kompilierzeit bei Sprachen wie Java zur Verfügung stehen, um zu validieren, dass der Anwendungscode korrekt ist, unterstützen viele zeitgemäße Frameworks zur Kompilierzeit Entwickler wenig oder gar nicht. Sie führen die Überprüfungen stattdessen zur Laufzeit durch und erzeugen im Fehlerfall diverse Runtime Exceptions, um zu informieren, dass der vorliegende Code falsch ist.