{"id":79987,"date":"2020-05-02T01:42:42","date_gmt":"2020-05-01T23:42:42","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/kak-quarkus-obedinyaet-microprofile-i-spring"},"modified":"2020-05-02T01:42:42","modified_gmt":"2020-05-01T23:42:42","slug":"kak-quarkus-obedinyaet-microprofile-i-spring","status":"publish","type":"post","link":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/kak-quarkus-obedinyaet-microprofile-i-spring","title":{"rendered":"Hvordan Quarkus kombinerer MicroProfile og Spring","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Hej alle sammen, og velkommen til det tredje indl\u00e6g i serien om Quarkus!<\/p>\n<p><img decoding=\"async\" alt=\"Hvordan Quarkus kombinerer MicroProfile og Spring\" src=\"\/wp-content\/uploads\/2020\/05\/d98ff470b49f8de1fa488a6818160969.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nN\u00e5r man udvikler Java-mikrotjenester, betragtes det ofte, at <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/blog\/2019\/02\/28\/jumpstart-microservices-microprofile-starter-beta\/\">Eclipse MicroProfile<\/a><\/noindex> og <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/topics\/spring-boot\/\">Spring Boot<\/a><\/noindex> \u2013 er separate og uafh\u00e6ngige API'er. Som standard bruger programm\u00f8rer ofte de API'er, de allerede er vant til, da det kr\u00e6ver meget tid at l\u00e6re nye rammer og runtime-komponenter. I dag vil vi fors\u00f8ge at forenkle indl\u00e6ringen af nogle popul\u00e6re <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/blog\/2018\/11\/21\/eclipse-microprofile-for-spring-boot-developers\/\">MicroProfile API'er til Spring-udviklere<\/a><\/noindex> og vise, hvordan man samtidig kan aktivere Spring API og nye nyttige funktioner. <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/\">Quarkus<\/a><\/noindex>.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nFor at v\u00e6re lidt mere specifik vil vi f\u00f8rst se p\u00e5 anvendelsesomr\u00e5det og detaljerne i, hvordan Quarkus underst\u00f8tter Spring API'er for at vise Spring-udviklere, hvordan de kan anvende MicroProfile API'er i deres daglige arbejde. Derefter vil vi tale om MicroProfile API'er, der vil v\u00e6re nyttige for Spring-udviklere ved oprettelse af mikrotjenester.<\/p>\n<p>Hvorfor netop Quarkus? For det f\u00f8rste er det live coding, hvilket betyder automatisk genindl\u00e6sning af alle \u00e6ndringer i MicroProfile API, Spring API og andre Java API'er, som udf\u00f8res med en enkelt kommando: mvn quarkus:dev. For det andet ser vi p\u00e5 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jclingan\/quarkus-spring-microprofile\">vores eksempel<\/a><\/noindex> tjenesten Person (den kompileres fra API-gr\u00e6nsefladerne Spring, MicroProfile og JPA til en bin\u00e6r fil ved hj\u00e6lp af den native GraalVM- image) starter p\u00e5 kun 0.055 sekunder og bruger omkring 90 MB i RAM (RSS) p\u00e5 RESTful-applikationens endpoint. Og selve kompileringen udf\u00f8res med en enkelt kommando: mvn package -Pnative.<\/p>\n<p>Vi vil ikke dykke ned i detaljerne omkring MicroProfile, men blot fors\u00f8ge at hj\u00e6lpe Spring-udviklere med at forst\u00e5, hvordan man kan bruge Spring API'er sammen med MicroProfile API'er i Quarkus.<\/p>\n<h3>Containere og Kubernetes<\/h3>\n<p>\nFor ikke at overbelaste denne artikel, vil vi her kun overveje de h\u00f8jniveaus aspekter af st\u00f8tten <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/developer-tools\/kubernetes\">Kubernetes<\/a><\/noindex>, da dette er vigtigt at forst\u00e5. Quarkus pr\u00e6senteres som Java-stakken til Kubernetes, den har til form\u00e5l at minimere hukommelsesforbruget og opstartstiden for Java-applikationer og tjenester, hvilket i sidste ende \u00f8ger deres t\u00e6thed p\u00e5 v\u00e6rten og reducerer de samlede omkostninger.<\/p>\n<p>Quarkus underst\u00f8tter ogs\u00e5 <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/kubernetes-resources\">autogenerering<\/a><\/noindex> af Kubernetes-ressourcer og tilbyder <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/\">manualen<\/a><\/noindex> for implementering p\u00e5 Kubernetes- og Red Hat OpenShift-platforme. Desuden genererer Quarkus automatisk Dockerfile.jvm (JVM-pakning) og Dockerfile.native (native binary pakning), som er n\u00f8dvendige for at oprette containere.<\/p>\n<p>Og endelig, med Kubernetes som m\u00e5lmilj\u00f8et, anvender Quarkus ikke Java-rammer i de tilf\u00e6lde, hvor tilsvarende funktionalitet er implementeret p\u00e5 niveauet for selve Kubernetes-platformen. Tabel 1 viser kortet med funktionel overensstemmelse mellem Kubernetes og de typiske Java-rammer, der anvendes af Spring-udviklere.<\/p>\n<p><i>Tabel 1. Kort over funktionel overensstemmelse mellem Java-rammer og Kubernetes.<\/i><\/p>\n<p>Funktionalitet<br \/>\nTraditionel Spring Boot<br \/>\nKubernetes<\/p>\n<p>Serviceopdagelse<br \/>\nEureka<br \/>\nDNS<\/p>\n<p>Konfiguration<br \/>\nSpring Cloud Config<br \/>\nConfig Maps \/ Secrets<\/p>\n<p>Lastbalancering<br \/>\nRibbon (p\u00e5 klientsiden)<br \/>\nService, Replication Controller (p\u00e5 serversiden)<\/p>\n<p><\/p>\n<h3>Kompilering og k\u00f8rsel af koden fra eksemplet<\/h3>\n<p>\nI denne artikel refererer vi til <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jclingan\/quarkus-spring-microprofile\">eksemplet p\u00e5 projektet<\/a><\/noindex>, hvor API-gr\u00e6nsefladerne fra Spring og MicroProfile bruges sammen, og selv den samme Java-klasse. Koden fra dette eksempel kan kompileres og k\u00f8res fra kommandolinjen, se n\u00e6rmere i README.md-filen.<\/p>\n<h3>API-gr\u00e6nsefladerne fra Spring Framework<\/h3>\n<p><\/p>\n<h4>Dependency Injection<\/h4>\n<p>\nQuarkus underst\u00f8tter en r\u00e6kke <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/cdi-reference\">API-gr\u00e6nseflader for Contexts and Dependency Injection (CDI)<\/a><\/noindex> og API-gr\u00e6nseflader for Spring Dependency Injection (Spring DI). Hvis du arbejder med MicroProfile, <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/blog\/2019\/09\/12\/jakarta-ee-8-the-new-era-of-java-ee-explained\/\">Java EE og Jakarta EE<\/a><\/noindex>, s\u00e5 er du allerede godt bekendt med CDI. P\u00e5 den anden side kan Spring-udviklere bruge Quarkus Extension for Spring DI API for at sikre kompatibilitet med Spring DI. Eksempler p\u00e5 brug af de underst\u00f8ttede Spring DI API'er findes i tabel 2.<\/p>\n<p>I <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jclingan\/quarkus-spring-microprofile\">projektet fra vores eksempel<\/a><\/noindex> anvender b\u00e5de CDI og Spring Dependency Injection. Yderligere oplysninger og eksempler om dette kan findes i Quarkus-guiden, der hedder <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/spring-di\">Spring DI Guide<\/a><\/noindex>.<\/p>\n<p><i>Tabel 2. Eksempler p\u00e5 brug af de underst\u00f8ttede API-gr\u00e6nseflader for Spring DI.<\/i><\/p>\n<p>Underst\u00f8ttede funktioner i Spring DI<br \/>\nEksempler<\/p>\n<p>Constructor Injection<\/p>\n<pre><code class=\"plaintext\">public PersonSpringController(\n   PersonSpringRepository personRepository,  \/\/ injiceret      \n   PersonSpringMPService personService) {    \/\/ injiceret\n      this.personRepository = personRepository;\n      this.personService = personService;\n}\n<\/code><\/pre>\n<p>Field Injection<br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/autowired\/\" class=\"user_link\">Autowired<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/value\/\" class=\"user_link\">V\u00e6rdi<\/a><\/noindex><\/p>\n<pre><code class=\"plaintext\">@Autowired\n@RestClient\nSalutationRestClient salutationRestClient;\n\n@Value(\"${fallbackSalutation}\")\nString fallbackSalutation;\n<\/code><\/pre>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/bean\/\" class=\"user_link\">Bean<\/a><\/noindex><br \/>\n@Configuration<\/p>\n<pre><code class=\"plaintext\">@Configuration\npublic class AppConfiguration {\n   @Bean(name = \"capitalizeFunction\")\n   public StringFunction capitalizer() {\n      return String::toUpperCase;\n   }\n}\n<\/code><\/pre>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/component\/\" class=\"user_link\">Component<\/a><\/noindex><\/p>\n<pre><code class=\"plaintext\">@Component(\"noopFunction\")\npublic class NoOpSingleStringFunction implements StringFunction {\n   @Override\n   public String apply(String s) {\n      return s;\n   }\n}\n<\/code><\/pre>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/service\/\" class=\"user_link\">Service<\/a><\/noindex><\/p>\n<pre><code class=\"plaintext\">@Service\npublic class MessageProducer {\n   @Value(\"${greeting.message}\")\n   String message;\n\n   public String getPrefix() {\n      return message;\n   }\n}\n<\/code><\/pre>\n<p><\/p>\n<h4>Web-ramme<\/h4>\n<p>\nMicroProfile-brugere vil s\u00e6tte pris p\u00e5, at Quarkus underst\u00f8tter JAX-RS, MicroProfile Rest Client, JSON-P og JSON-B som den grundl\u00e6ggende model for webprogrammering. Spring-udviklere vil ogs\u00e5 v\u00e6rds\u00e6tte den nyligt tilf\u00f8jede st\u00f8tte til Spring Web API i Quarkus, is\u00e6r de interfaces der besk\u00e6ftiger sig med REST. P\u00e5 samme m\u00e5de som med Spring DI er hovedm\u00e5let med underst\u00f8ttelsen af Spring Web API, at Spring-udviklere kan bruge Spring Web API sammen med MicroProfile API-interfaces. Eksempler p\u00e5 brug af de underst\u00f8ttede Spring Web API findes i tabel 3, og yderligere information og eksempler kan findes i Quarkus-guiden, der hedder <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/spring-web\">Spring Web Guide<\/a><\/noindex>.<\/p>\n<p><i>Tabel 3. Eksempler p\u00e5 brug af underst\u00f8ttede Spring Web API-interfaces.<\/i><\/p>\n<p>Underst\u00f8ttede funktioner i Spring Web<br \/>\nEksempler<\/p>\n<p>@RestController<br \/>\n@RequestMapping<\/p>\n<pre><code class=\"plaintext\">@RestController\n@RequestMapping(\"\/person\")\npublic class PersonSpringController {\n   ...\n   ...\n   ...\n}\n<\/code><\/pre>\n<p>@GetMapping<br \/>\n@PostMapping<br \/>\n@PutMapping<br \/>\n@DeleteMapping<br \/>\n@PatchMapping<br \/>\n@RequestParam<br \/>\n@RequestHeader<br \/>\n@MatrixVariable<br \/>\n@PathVariable<br \/>\n@CookieValue<br \/>\n@RequestBody<br \/>\n@ResponseStatus<br \/>\n@ExceptionHandler<br \/>\n@RestControllerAdvice (delvis)<\/p>\n<pre><code class=\"plaintext\">@GetMapping(path = \"\/greet\/{id}\",\n   produces = \"text\/plain\")\n   public String greetPerson(\n   @PathVariable(name = \"id\") long id) {\n   ...\n   ...\n   ...\n}\n<\/code><\/pre>\n<p><\/p>\n<h4>Spring Data JPA<\/h4>\n<p>\nMicroProfile-brugere vil ogs\u00e5 s\u00e6tte pris p\u00e5, at Quarkus underst\u00f8tter JPA med Hibernate ORM. Der er ogs\u00e5 gode nyheder for Spring-udviklere: Quarkus underst\u00f8tter de almindeligt anerkendte annotationer og typer inden for Spring Data JPA. Eksempler p\u00e5 brug af de underst\u00f8ttede Spring Data JPA API findes i tabel 4.<br \/>\nI <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jclingan\/quarkus-spring-microprofile\">projektet fra vores eksempel<\/a><\/noindex> bruger API-interfaces fra Spring Data JPA, og yderligere information er tilg\u00e6ngelig i Quarkus-guiden med titlen <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/spring-data-jpa-guide\">Spring Data JPA Guide<\/a><\/noindex>.<\/p>\n<p><i>Tabel 4. Eksempler p\u00e5 brug af underst\u00f8ttede Spring Data JPA API-interfaces.<\/i><\/p>\n<p>Underst\u00f8ttede funktioner i Spring Data JPA<br \/>\nEksempler<\/p>\n<p>CrudRepository<\/p>\n<pre><code class=\"plaintext\">public interface PersonRepository\n         extends JpaRepository,\n                 PersonFragment {\n   ...\n}\n<\/code><\/pre>\n<p>Repository<br \/>\nJpaRepository<br \/>\nPagingAndSortingRepository<\/p>\n<pre><code class=\"plaintext\">public class PersonRepository extends \n\n    Repository {\n\n    Person save(Person entity);\n\n    Optional findById(Person entity);\n}\n<\/code><\/pre>\n<p>Repository Fragments<\/p>\n<pre><code class=\"plaintext\">public interface PersonRepository\n         extends JpaRepository,\n                 PersonFragment {\n   ...\n}\n<\/code><\/pre>\n<p>Arv af foresp\u00f8rgselsmetoder<\/p>\n<pre><code class=\"plaintext\">public interface PersonRepository extends CrudRepository {\n\n    List findByName(String name);\n    \n    Person findByNameBySsn(String ssn);\n    \n    Optional \n       findByNameBySsnIgnoreCase(String ssn);\n\n    Boolean existsBookByYearOfBirthBetween(\n            Integer start, Integer end);\n}\n<\/code><\/pre>\n<p>Brugerdefinerede foresp\u00f8rgsler<\/p>\n<pre><code class=\"plaintext\">public interface MovieRepository\n         extends CrudRepository {\n\n    Movie findFirstByOrderByDurationDesc();\n\n    @Query(\"select m from Movie m where m.rating = ?1\")\n    Iterator findByRating(String rating);\n\n    @Query(\"from Movie where title = ?1\")\n    Movie findByTitle(String title);\n}\n<\/code><\/pre>\n<p><\/p>\n<h3>API-interfaces fra MicroProfile<\/h3>\n<p><\/p>\n<h4>Fejltolerance<\/h4>\n<p>\nFejltolerante konstruktioner er meget vigtige for at forhindre kaskadefejl og skabe p\u00e5lidelige mikroservicearkitekturer. Spring-udviklere har i mange \u00e5r brugt circuit-breakers til fejltolerance. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/Netflix\/Hystrix\">Hystrix<\/a><\/noindex>. Dog har Hystrix ikke v\u00e6ret opdateret i lang tid, mens MicroProfile's fejltolerance nu aktivt udvikles og har flere \u00e5rs produktionsbrug bag sig. Derfor anbefales det at anvende MicroProfile Fault Tolerance API'er i Quarkus for at \u00f8ge p\u00e5lideligheden af tjenester. Eksempler p\u00e5 anvendelse er vist i tabel 5. Yderligere oplysninger kan findes i Quarkus-h\u00e5ndbogen. <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/microprofile-fault-tolerance\">Fault Tolerance Guide<\/a><\/noindex>.<\/p>\n<p><i>Tabel 5. Eksempler p\u00e5 anvendelse af underst\u00f8ttede MicroProfile Fault Tolerance API'er.<\/i><\/p>\n<p>Funktioner i MicroProfile Fault Tolerance<br \/>\nDescription<br \/>\nEksempler<\/p>\n<p>@Asynchronous<\/p>\n<p>Udf\u00f8relse af logik i en separat tr\u00e5d<\/p>\n<pre><code class=\"plaintext\">@Asynchronous\n@Retry\npublic Future getSalutation() {\n   ...\n   return future;\n}\n<\/code><\/pre>\n<p>@Bulkhead<\/p>\n<p>Begr\u00e6nsning af antallet af samtidige anmodninger<\/p>\n<pre><code class=\"plaintext\">@Bulkhead(5)\npublic void fiveConcurrent() {\n   makeRemoteCall(); \/\/...\n}\n<\/code><\/pre>\n<p>@CircuitBreaker<\/p>\n<p>Intelligent fejlh\u00e5ndtering og genopretning fra fejl<\/p>\n<pre><code class=\"plaintext\">@CircuitBreaker(delay=500   \/\/ milliseconds\n   failureRatio = .75,\n   requestVolumeThreshold = 20,\n   successThreshold = 5)\n@Fallback(fallbackMethod = \"fallback\")\npublic String getSalutation() {\n   makeRemoteCall(); \/\/...\n}\n<\/code><\/pre>\n<p>@Fallback<\/p>\n<p>Kald alternativ logik ved fejl<\/p>\n<pre><code class=\"plaintext\">@Timeout(500) \/\/ milliseconds\n@Fallback(fallbackMethod = \"fallback\")\npublic String getSalutation() {\n   makeRemoteCall(); \/\/...\n}\n\npublic String fallback() {\n   return \"hello\";\n}\n<\/code><\/pre>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/retry\/\" class=\"user_link\">Retry<\/a><\/noindex><\/p>\n<p>Gentag ved foresp\u00f8rgselsfejl<\/p>\n<pre><code class=\"plaintext\">@Retry(maxRetries=3)\npublic String getSalutation() {\n   makeRemoteCall(); \/\/...\n}\n<\/code><\/pre>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/timeout\/\" class=\"user_link\">Timeout<\/a><\/noindex><\/p>\n<p>Tidskontrol ved fejl<\/p>\n<pre><code class=\"plaintext\">@Timeout(value = 500 )   \/\/ milliseconds\n@Fallback(fallbackMethod = \"fallback\")\npublic String getSalutation() {\n   makeRemoteCall(); \/\/...\n}\n<\/code><\/pre>\n<p><\/p>\n<h4>Kontrol af tjenester (Service Health)<\/h4>\n<p>\nKubernetes-platforme overv\u00e5ger sundheden af containere ved hj\u00e6lp af specielle tjenester. For at den underliggende platform kan overv\u00e5ge tjenester, bruger Spring-udviklere typisk tilpassede HealthIndicator og Spring Boot Actuator. I Quarkus kan dette g\u00f8res med MicroProfile Health, som som standard udf\u00f8rer livstjek (liveness check), men kan ogs\u00e5 konfigureres til samtidig at tjekke liv (liveness) og klarhed (readiness). Eksempler p\u00e5 anvendelse af underst\u00f8ttede MicroProfile Health API'er vises i tabel 6, og yderligere information er pr\u00e6senteret i Quarkus-h\u00e5ndbogen. <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/microprofile-health\">Health Guide<\/a><\/noindex>.<\/p>\n<p><i>Tabel 6. Eksempler p\u00e5 anvendelse af underst\u00f8ttede MicroProfile Health API'er.<\/i><\/p>\n<p>Funktioner i MicroProfile Health<br \/>\nDescription<br \/>\nEksempler<\/p>\n<p>@Liveness<\/p>\n<p>Platformen genstarter defekte containere applikationer.<br \/>\nEndpoint:<br \/>\nhost:8080\/health\/live<\/p>\n<pre><code class=\"plaintext\">@Liveness\npublic class MyHC implements HealthCheck {\n  public HealthCheckResponse call() {\n\n   ...\n   return HealthCheckResponse\n     .named(\"myHCProbe\")\n     .status(ready ? true:false)\n     .withData(\"mydata\", data)\n     .build();  \n}\n<\/code><\/pre>\n<p>@Readiness<\/p>\n<p>Platformen vil ikke sende trafik til containeriserede applikationer, hvis de ikke er klar.<br \/>\nEndpoint:<br \/>\nhost:8080\/health\/ready<\/p>\n<pre><code class=\"plaintext\">@Readiness\npublic class MyHC implements HealthCheck {\n  public HealthCheckResponse call() {\n\n   ...\n   return HealthCheckResponse\n     .named(\"myHCProbe\")\n     .status(live ? true:false)\n     .withData(\"mydata\", data)\n     .build();  \n}\n<\/code><\/pre>\n<p><\/p>\n<h4>M\u00e5linger<\/h4>\n<p>\nApplikationer giver metrics enten til operationelle form\u00e5l (for at overv\u00e5ge SLA-pr\u00e6stationsindikatorer) eller ikke-operationelle form\u00e5l (forretnings-SLA-metrics). Spring-udviklere leverer metrics via Spring Boot Actuator og Micrometer. P\u00e5 den anden side bruger Quarkus MicroProfile Metrics til at levere grundl\u00e6ggende metrics (JVM og operativsystem), leverand\u00f8r-metrics (Quarkus) og applikations-metrics. MicroProfile Metrics kr\u00e6ver, at implementeringen underst\u00f8tter outputformaterne JSON og OpenMetrics (Prometheus). Eksempler p\u00e5 brug af MicroProfile Metrics API er angivet i Tabel 7.<\/p>\n<p>I <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jclingan\/quarkus-spring-microprofile\">projektet fra vores eksempel<\/a><\/noindex> MicroProfile Metrics bruges til at levere applikationsmetrics. Yderligere oplysninger findes i Quarkus-h\u00e5ndbogen. <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/microprofile-metrics\">Metrics Guide<\/a><\/noindex>.<\/p>\n<p><i>Tabel 7. Eksempler p\u00e5 brug af MicroProfile Metrics API'er.<\/i><\/p>\n<p>Funktioner i MicroProfile Metrics<br \/>\nDescription<br \/>\nEksempler<\/p>\n<p>@Counted<\/p>\n<p>Angiver en counter-variabel, der t\u00e6ller antallet af kald til den annoterede objekt.<\/p>\n<pre><code class=\"plaintext\">@Counted(name = \"fallbackCounter\", \n  displayName = \"Fallback Counter\", \n  description = \"Fallback Counter\")\npublic String salutationFallback() {\n   return fallbackSalutation;\n}\n<\/code><\/pre>\n<p>@ConcurrentGauge<\/p>\n<p>Angiver en gauge-m\u00e5ler, der t\u00e6ller antallet af parallelle kald til den annoterede objekt.<\/p>\n<pre><code class=\"plaintext\">@ConcurrentGuage(\n  name = \"fallbackConcurrentGauge\", \n  displayName=\"Fallback Concurrent\", \n  description=\"Fallback Concurrent\")\npublic String salutationFallback() {\n   return fallbackSalutation;\n}\n<\/code><\/pre>\n<p>@Gauge<\/p>\n<p>Angiver en gauge-m\u00e5ler, der m\u00e5ler v\u00e6rdien af den annoterede objekt.<\/p>\n<pre><code class=\"plaintext\">@Metered(name = \"FallbackGauge\",\n   displayName=\"Fallback Gauge\",\n   description=\"Fallback frequency\")\npublic String salutationFallback() {\n   return fallbackSalutation;\n}\n<\/code><\/pre>\n<p>@Metered<\/p>\n<p>Angiver en meter-m\u00e5ler, der sporer hyppigheden af kald til den annoterede objekt.<\/p>\n<pre><code class=\"plaintext\">@Metered(name = \"MeteredFallback\",\n   displayName=\"Metered Fallback\",\n   description=\"Fallback frequency\")\npublic String salutationFallback() {\n   return fallbackSalutation;\n}\n<\/code><\/pre>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/metric\/\" class=\"user_link\">Metric<\/a><\/noindex><\/p>\n<p>Annotation, der indeholder metadata-information ved modtagelse af anmodning om at inds\u00e6tte eller generere metric.<\/p>\n<pre><code class=\"plaintext\">@Metric\n@Metered(name = \"MeteredFallback\",\n   displayName=\"Metered Fallback\",\n   description=\"Fallback frequency\")\npublic String salutationFallback() {\n   return fallbackSalutation;\n}\n<\/code><\/pre>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/timed\/\" class=\"user_link\">Timed<\/a><\/noindex><\/p>\n<p>Angiver en timer, der sporer varigheden af den annoterede objekt.<\/p>\n<pre><code class=\"plaintext\">@Timed(name = \"TimedFallback\",\n   displayName=\"Timed Fallback\",\n   description=\"Fallback delay\")\npublic String salutationFallback() {\n   return fallbackSalutation;\n}\n<\/code><\/pre>\n<p>\n<b>Metrics Endpoints<\/b><\/p>\n<p>Applikationsmetrikker <noindex><a rel=\"nofollow\" href=\"http:\/\/localhost\">localhost<\/a><\/noindex>:8080\/metrics\/application<br \/>\nBasismetrikker <noindex><a rel=\"nofollow\" href=\"http:\/\/localhost\">localhost<\/a><\/noindex>:8080\/metrics\/base<br \/>\nLeverand\u00f8rmetrikker <noindex><a rel=\"nofollow\" href=\"http:\/\/localhost\">localhost<\/a><\/noindex>:8080\/metrics\/vendor<br \/>\nAlle metrikker <noindex><a rel=\"nofollow\" href=\"http:\/\/localhost\">localhost<\/a><\/noindex>:8080\/metrics<\/p>\n<h4>Rest-client MicroProfile<\/h4>\n<p>\nMikrotjenester tilbyder ofte RESTful slutpunkter, som kr\u00e6ver de rette klient-API'er for at fungere. For at bruge RESTful slutpunkter anvender Spring-udviklere typisk RestTemplate. Quarkus tilbyder dog MicroProfile Rest Client API'er til dette form\u00e5l, eksempler p\u00e5 brug kan findes i tabel 8.<\/p>\n<p>I <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jclingan\/quarkus-spring-microprofile\">projektet fra vores eksempel<\/a><\/noindex> Brug af RESTful slutpunkter udf\u00f8res med MicroProfile Rest Client. Yderligere oplysninger og eksempler p\u00e5 dette kan findes i Quarkus-h\u00e5ndbogen. <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/rest-client\">Rest Client Guide<\/a><\/noindex>.<\/p>\n<p><i>Tabel 8. Eksempler p\u00e5 brug af MicroProfile Rest Client API'er.<\/i><\/p>\n<p>Funktioner i MicroProfile Rest Client<br \/>\nDescription<br \/>\nEksempler<\/p>\n<p>@RegisterRestClient<\/p>\n<p>Registrerer en typet Java-interface som en REST-klient<\/p>\n<pre><code class=\"plaintext\">@RegisterRestClient\n@Path(\"\/\")\npublic interface MyRestClient {\n    @GET\n    @Produces(MediaType.TEXT_PLAIN)\n    public String getSalutation();\n}\n<\/code><\/pre>\n<p>@RestClient<\/p>\n<p>Markerer injektionen af en instans af det typede REST-klientinterface<\/p>\n<pre><code class=\"plaintext\">@Autowired \/\/ or @Inject\n@RestClient\nMyRestClient restClient;\n<\/code><\/pre>\n<p>Invocation<\/p>\n<p>Kalder REST slutpunktet<\/p>\n<pre><code class=\"plaintext\">System.out.println(\n   restClient.getSalutation());\n<\/code><\/pre>\n<p>mp-rest\/url<\/p>\n<p>Angiver REST slutpunktet<\/p>\n<pre><code class=\"plaintext\">application.properties:\norg.example.MyRestClient\/mp-rest\/url=\n   http:\/\/localhost:8081\/myendpoint\n<\/code><\/pre>\n<p><\/p>\n<h3>Resum\u00e9<\/h3>\n<p>\nI denne blog, som is\u00e6r er nyttig for Spring-udviklere, har vi kort gennemg\u00e5et, hvordan man i Quarkus bruger Spring API'er sammen med MicroProfile API'er til at udvikle Java mikrotjenester og derefter kompilere dem til nativen bin\u00e6rkode, der sparer hundredvis af megabyte RAM og starter p\u00e5 f\u00e5 millisekunder.<\/p>\n<p>Som du allerede ved, kan yderligere oplysninger om underst\u00f8ttelse af Spring og MicroProfile API'er samt en masse anden nyttig information findes i <noindex><a rel=\"nofollow\" href=\"https:\/\/quarkus.io\/guides\/\">Quarkus-h\u00e5ndb\u00f8gerne<\/a><\/noindex>.<br \/>\n<br \/>Kilde: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/redhatrussia\/blog\/497504\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442, \u0438 \u0441 \u0432\u0430\u043c\u0438 \u0442\u0440\u0435\u0442\u0438\u0439 \u043f\u043e\u0441\u0442 \u0438\u0437 \u0441\u0435\u0440\u0438\u0438 \u043f\u0440\u043e Quarkus! \u041f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 Java-\u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0447\u0430\u0441\u0442\u043e \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e Eclipse MicroProfile \u0438 Spring Boot \u2013 \u044d\u0442\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0438 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0435 \u0434\u0440\u0443\u0433 \u043e\u0442 \u0434\u0440\u0443\u0433\u0430 API. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u044b, \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0442\u0435 API, \u043a \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043e\u043d\u0438 \u0443\u0436\u0435 \u043f\u0440\u0438\u0432\u044b\u043a\u043b\u0438, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432 \u0438 runtime-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u044b [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":79988,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-79987","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442, \u0438 \u0441 \u0432\u0430\u043c\u0438 \u0442\u0440\u0435\u0442\u0438\u0439 \u043f\u043e\u0441\u0442 \u0438\u0437 \u0441\u0435\u0440\u0438\u0438 \u043f\u0440\u043e Quarkus!\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/kak-quarkus-obedinyaet-microprofile-i-spring\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"da_DK\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041a\u0430\u043a Quarkus \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 MicroProfile \u0438 Spring | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442, \u0438 \u0441 \u0432\u0430\u043c\u0438 \u0442\u0440\u0435\u0442\u0438\u0439 \u043f\u043e\u0441\u0442 \u0438\u0437 \u0441\u0435\u0440\u0438\u0438 \u043f\u0440\u043e Quarkus!\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/kak-quarkus-obedinyaet-microprofile-i-spring\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-05-01T23:42:42+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-05-01T23:42:42+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Hvordan Quarkus kombinerer MicroProfile og Spring | ProHoster","description":"Hej alle sammen, og velkommen til det tredje indl\u00e6g i serien om Quarkus!","canonical_url":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/kak-quarkus-obedinyaet-microprofile-i-spring","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"da_DK","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041a\u0430\u043a Quarkus \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 MicroProfile \u0438 Spring | ProHoster","og:description":"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442, \u0438 \u0441 \u0432\u0430\u043c\u0438 \u0442\u0440\u0435\u0442\u0438\u0439 \u043f\u043e\u0441\u0442 \u0438\u0437 \u0441\u0435\u0440\u0438\u0438 \u043f\u0440\u043e Quarkus!","og:url":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/kak-quarkus-obedinyaet-microprofile-i-spring","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-05-01T23:42:42+00:00","article:modified_time":"2020-05-01T23:42:42+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"79987","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 16:27:13","updated":"2022-09-30 14:08:43","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/79987","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/comments?post=79987"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/79987\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media\/79988"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media?parent=79987"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/categories?post=79987"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/tags?post=79987"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}