Inleiding tot Micronaut Framework

1. Wat is Micronaut

Micronaut is een op JVM gebaseerd raamwerk voor het bouwen van lichtgewicht, modulaire applicaties. Ontwikkeld door OCI, hetzelfde bedrijf dat Grails heeft gemaakt, Micronaut is het nieuwste framework dat is ontworpen om het creëren van microservices snel en eenvoudig te maken.

Hoewel Micronaut enkele functies bevat die vergelijkbaar zijn met bestaande frameworks zoals Spring, heeft het ook enkele nieuwe functies die hem onderscheiden. En met ondersteuning voor Java, Groovy en Kotlin biedt het verschillende manieren om applicaties te maken.

2. Belangrijkste kenmerken

Een van de meest opwindende kenmerken van Micronaut is het injectiemechanisme voor compilatietijdafhankelijkheid. De meeste frameworks gebruiken reflectie en proxy's om afhankelijkheidsinjectie tijdens runtime uit te voeren. Micronaut bouwt zijn afhankelijkheidsinjectiegegevens echter tijdens het compileren op. Het resultaat is een snellere opstart van applicaties en een kleinere geheugenvoetafdruk.

Een ander kenmerk is de eerste klas ondersteuning voor reactief programmeren, zowel voor clients als servers. De keuze voor een specifieke reactieve implementatie wordt aan de ontwikkelaar overgelaten aangezien zowel RxJava als Project Reactor worden ondersteund.

Micronaut heeft ook verschillende functies die het een uitstekend raamwerk maken voor het ontwikkelen van cloud-native applicaties. Het ondersteunt meerdere tools voor het opsporen van services, zoals Eureka en Consul, en werkt ook met verschillende gedistribueerde traceersystemen zoals Zipkin en Jaeger.

Het biedt ook ondersteuning voor het maken van AWS-lambda-functies, waardoor het eenvoudig wordt om serverloze applicaties te maken.

3. Aan de slag

De gemakkelijkste manier om aan de slag te gaan, is SDKMAN gebruiken:

> sdk installeer micronaut 1.0.0.RC2

Hiermee worden alle binaire bestanden geïnstalleerd die we nodig hebben om Micronaut-applicaties te bouwen, testen en implementeren. Het biedt ook de Micronaut CLI-tool, waarmee we gemakkelijk nieuwe projecten kunnen starten.

De binaire artefacten zijn ook beschikbaar op Sonatype en GitHub.

In de volgende secties zullen we enkele kenmerken van het framework bekijken.

4. Afhankelijkheidsinjectie

Zoals eerder vermeld, behandelt Micronaut afhankelijkheidsinjectie tijdens het compileren, wat anders is dan de meeste IoC-containers.

Het is echter nog steeds ondersteunt volledig JSR-330-annotaties dus werken met bonen is vergelijkbaar met andere IoC-frameworks.

Om een ​​boon automatisch in onze code te plaatsen, gebruiken we @Injecteren:

@Inject privé EmployeeService-service;

De @Injecteren annotatie werkt net als @Autowired en kan worden gebruikt op velden, methoden, constructors en parameters.

Standaard worden alle bonen als prototype gebruikt. We kunnen snel singletonbonen maken met @Singleton. Als meerdere klassen dezelfde bean-interface implementeren, @Primair kan worden gebruikt om ze te deconflicteren:

@Primary @Singleton openbare klasse BlueCar implementeert auto {}

De @Vereist annotatie kan worden gebruikt wanneer bonen optioneel zijn, of om alleen automatisch bedraden uit te voeren wanneer aan bepaalde voorwaarden is voldaan.

In dit opzicht gedraagt ​​het zich net als de Spring Boot @Voorwaardelijk annotaties:

@Singleton @Requires (bonen = DataSource.class) @Requires (property = "enabled") @Requires (missingBeans = EmployeeService) @Requires (sdk = Sdk.JAVA, value = "1.8") openbare klasse JdbcEmployeeService implementeert EmployeeService {}

5. Het bouwen van een HTTP-server

Laten we nu eens kijken naar het maken van een eenvoudige HTTP-servertoepassing. Om te beginnen gebruiken we SDKMAN om een ​​project te maken:

> mn create-app hallo-world-server -build maven

Hiermee wordt een nieuw Java-project gemaakt met Maven in een map met de naam hallo-world-server. In deze map vinden we de broncode van onze hoofdtoepassing, het Maven POM-bestand en andere ondersteuningsbestanden voor het project.

De standaardtoepassing die heel eenvoudig is:

openbare klasse ServerApplication {openbare statische leegte hoofd (String [] args) {Micronaut.run (ServerApplication.class); }}

5.1. HTTP blokkeren

Op zichzelf zal deze applicatie niet veel doen. Laten we een controller toevoegen die twee eindpunten heeft. Beiden zullen een begroeting retourneren, maar men zal de KRIJGEN HTTP-werkwoord, en de andere gebruikt POST:

@Controller ("/ greet") openbare klasse GreetController {@Inject private GreetingService greetingService; @Get ("/ {name}") openbare String-begroeting (String-naam) {return greetingService.getGreeting () + naam; } @Post (waarde = "/ {naam}", consumes = MediaType.TEXT_PLAIN) openbare String setGreeting (@Body String naam) {return greetingService.getGreeting () + naam; }}

5.2. Reactieve IO

Standaard implementeert Micronaut deze eindpunten met behulp van traditionele blokkerings-I / O. Echter, we kunnen snel niet-blokkerende eindpunten implementeren door alleen het retourtype te wijzigen in een willekeurig reactief niet-blokkerend type.

Met RxJava kunnen we bijvoorbeeld Waarneembaar. Evenzo kunnen we bij gebruik van Reactor terugkeren Mono of Flux gegevenstypen:

@Get ("/ {name}") openbare Mono greet (String naam) {return Mono.just (greetingService.getGreeting () + naam); }

Voor zowel blokkerende als niet-blokkerende eindpunten is Netty de onderliggende server die wordt gebruikt om HTTP-verzoeken af ​​te handelen.

Normaal gesproken worden de verzoeken afgehandeld op de belangrijkste I / O-threadpool die bij het opstarten wordt gemaakt, waardoor ze worden geblokkeerd.

Wanneer echter een niet-blokkerend gegevenstype wordt geretourneerd door een controller-eindpunt, gebruikt Micronaut de Netty-gebeurtenislusthread, waardoor het hele verzoek niet-blokkerend wordt.

6. Bouwen van een HTTP-client

Laten we nu een client bouwen om de eindpunten te gebruiken die we zojuist hebben gemaakt. Micronaut biedt twee manieren om HTTP-clients te maken:

  • Een declaratieve HTTP-client
  • Een programmatische HTTP-client

6.1 Declaratieve HTTP-client

De eerste en snelste manier om te creëren, is door een declaratieve benadering te gebruiken:

@Client ("/ greet") openbare interface GreetingClient {@Get ("/ {name}") String greet (String naam); }

Merk op hoe we implementeren geen enkele code om onze service te bellen. In plaats daarvan begrijpt Micronaut hoe de service moet worden gebeld via de methodehandtekening en annotaties die we hebben verstrekt.

Om deze client te testen, kunnen we een JUnit-test maken die de ingesloten server-API gebruikt om een ​​ingesloten instantie van onze server uit te voeren:

openbare klasse GreetingClientTest {privé EmbeddedServer-server; privé-client van GreetingClient; @Before public void setup () {server = ApplicationContext.run (EmbeddedServer.class); client = server.getApplicationContext (). getBean (GreetingClient.class); } @After public void cleanup () {server.stop (); } @Test public void testGreeting () {assertEquals (client.greet ("Mike"), "Hallo Mike"); }}

6.2. Programmatische HTTP-client

We hebben ook de mogelijkheid om een ​​meer traditionele klant te schrijven als we meer controle over het gedrag en de implementatie ervan nodig hebben:

@Singleton openbare klasse ConcreteGreetingClient {privé RxHttpClient httpClient; openbare ConcreteGreetingClient (@Client ("/") RxHttpClient httpClient) {this.httpClient = httpClient; } public String greet (String naam) {HttpRequest req = HttpRequest.GET ("/ greet /" + naam); retourneer httpClient.retrieve (req) .blockingFirst (); } openbare Single greetAsync (String naam) {HttpRequest req = HttpRequest.GET ("/ async / greet /" + naam); return httpClient.retrieve (req) .first ("Er is een fout opgetreden"); }}

De standaard HTTP-client gebruikt RxJava, dus kan gemakkelijk werken met blokkerende of niet-blokkerende oproepen.

7. Micronaut CLI

We hebben de Micronaut CLI-tool hierboven al in actie gezien toen we deze gebruikten om ons voorbeeldproject te maken.

In ons geval hebben we een zelfstandige applicatie gemaakt, maar deze heeft ook verschillende andere mogelijkheden.

7.1. Federatie projecten

In Micronaut is een federatie slechts een groep zelfstandige applicaties die onder dezelfde directory staan. Door federaties te gebruiken, kunnen we ze gemakkelijk samen beheren en ervoor zorgen dat ze dezelfde standaardinstellingen en instellingen krijgen.

Wanneer we de CLI-tool gebruiken om een ​​federatie te genereren, zijn dezelfde argumenten nodig als de create-app opdracht. Het zal een projectstructuur op het hoogste niveau creëren en elke zelfstandige app zal van daaruit in zijn submap worden gemaakt.

7.2. Kenmerken

Bij het maken van een zelfstandige applicatie of federatie kunnen we beslissen welke functies onze app nodig heeft. Dit helpt ervoor te zorgen dat de minimale set afhankelijkheden in het project wordt opgenomen.

We specificeren functies met behulp van de -features argument en het leveren van een door komma's gescheiden lijst van feature namen.

We kunnen een lijst met beschikbare functies vinden door de volgende opdracht uit te voeren:

> mn profile-info service Aangeboden functies: -------------------- * annotation-api - Voegt Java annotatie-API toe * config-consul - Voegt ondersteuning toe voor gedistribueerde configuratie met consul * discovery-consul - Voegt ondersteuning toe voor Service Discovery met Consul * discovery-eureka - Voegt ondersteuning toe voor Service Discovery met Eureka * groovy - Creëert een Groovy-applicatie [...] Meer functies beschikbaar

7.3. Bestaande projecten

We kunnen de CLI-tool ook gebruiken om bestaande projecten aan te passen. Hierdoor kunnen we bonen, klanten, controllers en meer maken. Wanneer we het mn commando vanuit een bestaand project, hebben we een nieuwe set commando's beschikbaar:

> mn help | Commandonaam Commandobeschrijving ---------------------------------------------- - create-bean Maakt een singleton bean create-client Maakt een clientinterface create-controller Maakt een controller en bijbehorende test create-job Maakt een job met geplande methode

8. Conclusie

In deze korte introductie van Micronaut hebben we gezien hoe gemakkelijk het is om zowel blokkerende als niet-blokkerende HTTP-servers en clients te bouwen. We hebben ook enkele kenmerken van de CLI onderzocht.

Maar dit is slechts een kleine greep uit de functies die het biedt. Er is ook volledige ondersteuning voor serverloze functies, service-detectie, gedistribueerde tracering, monitoring en metrische gegevens, een gedistribueerde configuratie en nog veel meer.

En hoewel veel van zijn functies zijn afgeleid van bestaande frameworks zoals Grails en Spring, heeft het ook tal van unieke functies waardoor het op zichzelf opvalt.

Zoals altijd kunnen we de voorbeeldcode hierboven vinden in onze GitHub-opslagplaats.