Micronaut2.0:面向模块化、可测试应用程序的全栈Java框架

2020-06-27 16:12:03

Micronaut是一个现代的、基于JVM的全栈Java框架,旨在构建模块化的、易于测试的JVM应用程序,并支持Java、Kotlin和Groovy语言。

Micronaut是由Grails框架的创建者开发的,它的灵感来自于多年来使用Spring、Spring Boot和Grails构建从单块到微服务的真实世界应用程序的经验教训。

使用Micronaut,您可以构建消息驱动应用程序、命令行应用程序、HTTP服务器等,而对于Microservices,Micronaut还提供:

同时,Micronaut的目标是通过提供以下功能来避免Spring、Spring Boot和Grails等框架的缺点:

从历史上看,Spring和Grails等框架不适合在无服务器功能、Android应用程序或低内存占用微服务等场景中运行。相比之下,Micronaut被设计成适用于所有这些场景。

这一目标是通过使用Java的注释处理器(可在任何支持它们的JVM语言上使用)以及构建在Netty上的HTTP服务器和客户端来实现的。为了提供与Spring和Grails类似的编程模型,这些批注处理器预编译必要的元数据,以便执行DI、定义AOP代理并将应用程序配置为在低内存环境中运行。

Micronaut中的许多API在很大程度上受到Spring和Grails的启发。这是经过设计的,有助于让开发人员快速掌握最新情况。

在此版本中,启动时间得到了进一步改进,新应用程序的典型启动时间缩短了约20%。

Bean自省已得到改进,可以支持静态创建器方法、接口和枚举。这意味着您可以使用私有实现在接口上定义Bean自检,例如:

导入返回示例{string getName();@创建者静态示例Create(String Name){io.micronaut.core.annotation.Creator;@io.micronaut.core.annotation.Introspectedinterface()->;Name;}}。

Micronaut的依赖项注入实现已得到改进,现在您可以接收任何@Factory方法的InjectionPoint实例。这使得定制如何在注入Bean时基于注释元数据创建Bean成为可能。

工厂方法可以接收注入点并根据值创建客户端:

@BeanProtected DefaultHttpClient httpClient(InjectionPoint<;?>;InjectionPoint){String url=metadata.stringValue(Client.class).orElse(null);if(url!=NULL){返回新的DefaultHttpClient(URL);}Else{返回新的DefaultHttpClient();}}。

Bean的急切初始化在某些情况下很有用,例如在AWS Lambda上,分配给Lamdba构造的CPU资源多于执行的CPU资源。因此,对于Micronaut 2.0,您可以使用ApplicationContextBuilder接口指定是要急于初始化配置还是所有单例:

公共类应用程序{public static void main(String[]args){Micronaut.build(Args).agerInitSingletons(True)(1).mainClass(Application.class).start();}}。

还可以使用ageerInitConfiguration来初始化所有的@ConfigurationProperties bean,从而只急切地进行初始化配置。

在Micronaut1.x中,Google分布式JSR-305注释库(com.google.code.findbugs:jsr305)用于使用javax.notation包中包含的注释在Micronaut API的接口上指定@Nullable和@NonNull。

由于JSR-305已被取消,并且此依赖项存在潜在的许可问题(通过使用javax名称空间),以及Java9+上的交叉包与模块系统存在问题,Micronaut2.x切换到SpotBugs项目提供的SpotBugs-Annotation模块。

建议Micronaut用户改用此API(尽管继续支持javax.nottation.Nullable和javax.nottation.NotNull注释)。

Micronaut用于CLI的mn命令已经用Micronaut本身重写,现在编译成Linux、MacOSX和Windows上可用的本机映像。

运行curlopapi获取更多关于如何使用https://launch.micronaut.io的说明,或者访问openapi文档。

从另一个Micronaut项目的根运行mn Feature-diff--Feature=[Feature Name],以创建启用该功能所需应用的更改的差异。例如:

$MN FEATURE-DIFF--FEATURES=azure-Function-Micronaut-cli.yml+Micronaut-cli.yml@@-3,4+3,4@@testFramework:junit源语言:Java buildTool:Gradle-Feature:[app-name,application,gradle,http-client,java,junit,logback,netty-server,shade,yaml]+Feature:[app-name,application,azure-function,azure。:";2.0";,+";扩展包";:{+";id";:";Microsoft.Azure.Functions.ExtensionBundle";,+";版本";:";[1.*,2.0.0)";+}+}。

Microronaut对GraalVM本机映像的支持已脱离实验状态,这巩固了我们继续改善对本机映像支持的承诺。

不再需要为您的本机映像构建配置静态资源。对于src/main/resources中的所有资源,Micronaut-graal注释处理器将自动为您执行此操作。

通过JDBC或Hibernate/JPA连接到数据库不再需要提供额外的GraalVM相关配置。Micronaut通过GraalVM本机映像自动支持以下驱动程序:

Micronaut Flyway模块已更新为GraalVM本机映像支持,因此您现在可以在本机映像中运行数据库迁移。

Micronaut AWS模块2.0版包括对大多数v2 AWS API(包括S3、Dynamo DB、SES、SNS和SQS)的本机映像支持,这将有助于使用Micronaut+GraalVM开发本机AWS Lambda函数。

Micronaut jOOQ模块包括对Native Image的支持,并且可以将其与SimpleFlatMapper一起使用。

Micronaut Redis模块包括对本机映像的支持。由于生菜驱动程序的工作方式,仍然有一些未决的用例无法工作。确保您阅读了文档。

Micronaut现在提供了一个新的父POM,可以在Maven项目中使用它来快速设置:

上面提到的父POM包括一个新的Micronaut Maven插件,该插件支持在开发过程中自动重启应用程序。只需运行以下命令:

对于创建新应用程序的Gradle用户,使用的是与JDK14兼容的Gradle 6.5。

由于改进了对Gradle增量注释处理的支持,针对Java和Kotlin的Micronaut2构建Gradle的速度应该会大大加快。

Micronaut 2.0将新的共享默认Netty EventLoopGroup用于服务器工作线程和客户端请求线程。这减少了上下文切换并提高了资源利用率。

有关如何配置默认EventLoopGroup和添加每个客户端配置的其他‘EventLoopGroup’的信息,请参阅HTTP客户端配置部分。

此外,从Micronaut2.0开始,默认情况下所有操作都在EventLoop上执行,用户可以选择使用新的@ExecuteOn注释来指定指定的执行器,以便在需要时在其上执行操作(例如,将阻塞操作(如与JPA/JDBC的交互)卸载到特定的线程池)。

现在可以使用@RequestBean注释将POJO参数的属性绑定到@Controller以请求参数、标头等。

Micronaut现在支持创建Servlet应用程序,用户可以使用命令行创建以流行的Servlet容器为目标的应用程序:

$Mn create-app myapp--功能jetty-server#for Jetty$Mn create-app myapp--功能tomcat-server#for Tomcat$Mn create-app myapp--功能Undertow-server#

Micronaut现在将正确处理HTTP Accept报头,并使用服务器端内容协商为指定的接受媒体类型挑选最合适的路由。

这也适用于@Error路由,从而可以针对不同的内容类型发送不同的错误响应。

Microronaut现在将处理VCAP_APPLICATION和VCAP_SERVICES环境变量,并将其视为属性源。

不再需要使用@Client(..)。若要注入默认RxHttpClient实例,请执行以下操作。现在,您只需使用以下命令即可注入默认客户端:

如果在请求时没有提供主机,将抛出NoHostException。

新增了用于编写API网关和代理请求的API。有关详细信息,请参阅ProxyHttpClient上的文档。

现在可以控制各个端点方法的灵敏度。@Sensitive注释可以应用于端点方法,以允许某些方法具有与提供给端点注释的值不同的敏感度。

RxJava2的规范机制已经过改进,可以解决MDC的问题并减小反应性堆栈跟踪的大小。感谢丹尼斯·斯捷潘诺夫和拉霍斯·盖西在这方面的贡献。

您可以从Micronaut启动或通过命令行生成Micronaut+KTOR应用程序。

新的Kotlin扩展功能可以让Kotlin+Micronaut体验更好一点。

您现在可以使用Micronaut编写针对Google Cloud函数的无服务器函数。有关更多信息,请参阅Micronaut GCP文档和示例应用程序。

您现在可以使用Microronaut编写面向Microsoft Azure的无服务器函数。有关更多信息,请参阅Micronaut Azure文档和示例应用程序。

Micronaut AWS 2.0.0在支持AWS Lambda和AWS方面进行了大量改进,包括针对AWS SDK 2.0的新客户端模块、对Lambda的冷启动改进以及对Amazon Alexa支持的改进。

Micronaut比以往任何时候都更加模块化,现在有几个组件可以在单独的模块中使用,并对这些模块进行升级。

缓存已经移到了一个单独的模块中,并脱离了Micronaut-Runtime。如果您需要缓存(包括io.micronaut.cache.notation中的注释),您只需要为您感兴趣的缓存提供者添加单独的模块(例如,Caffeine、Redis、Hazelcast等)。

Micronaut SQL已改进为默认使用Micronaut事务管理(使Spring管理成为可选的),并包括对Jdbi的支持(感谢Dan Maas提供的这一贡献)。

此外,还添加了对Oracle Universal Connection Pool的支持。感谢托德·夏普的这一贡献。

安全模块进行了许多更改,以改进API并引入新功能以支持更广泛的用例。

虽然RxJava2仍然是默认的,但是已经为其他反应库添加了单独的模块。

新的RxJava3和反应器模块中包括RxHttpClient的变体,分别称为Rx3HttpClient和ReactorHttpClient。

本节介绍将Micronaut 1.x应用程序升级到Micronaut 2.x所需的步骤。

如果您的应用程序确实阻塞了I/O,比如通过JDBC或JPA进行通信,那么您应该使用@ExecuteOn注释来注释所有与这些阻塞资源交互的控制器,指定默认的I/O线程池或您配置的管理器来处理这些阻塞交互的线程池。例如:

导入io.micronaut.http.notation.*;import io.micronaut.Scheduling.TaskExecutors;导入io.micronaut.scheduling.annotation.ExecuteOn;@Controller(";/executeOn/people";)public类PersonController{Private Final PersonService PersonService;PersonController(PersonService PersonService){this.sonService=PersonService;}@Get(";/{Name}";)@ExecuteOn(TaskExecutors.IO)(1)Person ByName(String Name){Return PersonService.findByName(Name)。

import io.micronaut.http.notation.*import io.micronaut.Scheduling.TaskExecutorsimport io.micronaut.scheduling.annotation.ExecuteOn@Controller(";/executeOn/people";)class PersonController{Private Final PersonService Person Service PersonService PersonController(PersonService PersonService){this.sonService=PersonService}@Get(";/{Name}";)@ExecuteOn(TaskExecutors.IO)(1)Person ByName(String Name){Return PersonService.findByName(Name)}}

import io.micronaut.http.notation.*import io.micronaut.Scheduling.TaskExecutorsimport io.micronaut.scheduling.annotation.ExecuteOn@Controller(";/executeOn/people";)class个人控制器(私有ValPersonService:PersonService){@GET(";/{Name}";)@ExecuteOn(TaskExecutors.IO)(1)FUN ByName(Name:String):Person{Return PersonService.findByName(Name)}}。

如果您希望返回到Micronaut1.x中定义的前一行为,您可以在配置中将micronaut.server.thread-select设置为auto。

如果您的应用程序由于io.micronaut.cache中缺少类而无法编译,则需要添加对缓存实现的依赖项,例如,默认的缓存实现是Caffeine,这可以使用以下依赖项进行恢复:

如果您的应用程序无法编译javax.Annotation包中的引用类(如@Nullable和@Nonnull),则应该更新您的项目,以从Spot Bugs导入edu.umd.cs.findbugs.Annotation。

一些依赖项具有新的Maven组ID,因此您可能需要更新您的依赖项。下表汇总了对组ID的更改:

AWS功能(包括对AWS ParameterStore、AWS Route53和AWS Lambda Function Client的支持)已移出Micronaut核心,因此,如果您需要AWS相关功能,则应使用必要的模块。

在Micronaut1.2中不推荐使用的类io.micronaut.discovery.kubernetes.KubernetesDiscoveryClient,现在已从Micronaut2.0中删除。取而代之的是新的Micronaut Kubernetes模块,它改进了对在Kubernetes集群中运行Micronaut应用程序的支持,包括对Kubernetes配置地图、密码等的支持。

对于Micronaut2.0,我们建议您使用基于Micronaut的本地事务管理,而不是其他替代方案,如Spring Transaction Management。

您将使用JavaEE7javax.transaction.Transaction注释和io.micronaut.transaction.nottation.ReadOnly来标记您的事务分界。

要使用这些批注,您必须在批注处理器配置中包括Micronaut-Data-Processor相关性:

导入io.micronaut.spring.tx.annotation.Transactional;.@Singletonpublic类GenreRepositoryImpl实现了GenRepository{.。@Transaction(readOnly=true)public可选<;genre>;findById(@NotNull Long ID){.。}@事务性公共类型保存(@NotBlank字符串名称){.。}}。

import javax.transaction.Transaction;import io.micronaut.transaction.annotation.ReadOnly;.@Singletonpublic类GenreRepositoryImpl实现GenRepository{.。@ReadOnly public可选<;genre>;findById(@NotNull Long ID){.。}@事务性公共类型保存(@NotBlank字符串名称){.。}}。

Micronaut2默认使用Groovy3和Spock 2,这两个版本都在语言和测试框架级别进行了重大更改。

面向Groovy用户的Micronaut2的一些特性目前处于预览状态,包括GORM7.1和Spock 2支持,因为这些框架还没有稳定的版本。

对于Spock 2,最重要的变化是Spock 2不再支持JUnit4和相关的JUnit4测试运行程序,取而代之的是JUnit5平台。

在Gradle构建的情况下,此更改意味着当使用Spock 2升级到Micronaut2时,您可能会发现您的测试根本不执行,这会给您一种错误的安全感,即升级是成功的。

要确保您的Spock 2测试在Micronaut 2 Gradle版本中运行,您必须将以下配置添加到您的版本中。gradle以启用JUnit 5平台:

如果上面的用例不包括您的用例,请参阅破坏更改一节,以获得在此版本中被视为破坏的其他更改的列表。

以下各节将带您快速入门,了解如何使用Micronaut设置基本的Hello World应用程序。

在开始之前,请确保您安装了Java8或更高版本的SDK,并且建议您安装合适的IDE,如IntelliJ IDEA。

要按照快速入门操作,还建议您安装Micronaut CLI。

在Unix系统上安装Micronaut的最佳方式是使用SDKMAN,它极大地简化了多个Micronaut版本的安装和管理。

$MN|正在启动交互模式.|输入要运行的命令名。使用TAB完成:MN>;

$MN|正在启动交互模式.|输入要运行的命令名。使用TAB完成:MN>;

$MN|正在启动交互模式.|输入要运行的命令名。使用TAB完成:MN>;

您现在应该能够从命令提示符运行Micronaut CLI,如下所示:

$MN|正在启动交互模式.|输入要运行的命令名。使用TAB完成:MN>;

在您的shell配置文件(如果您使用的是Bash shell,则为~/.bash_profile)中,导出MICRONOT_HOME目录并将CLI路径添加到您的路径中:

$MN|正在启动交互模式.|输入要运行的命令名。使用TAB完成:MN>;

您还可以使用以下命令SDK install Micronaut dev/path/to/checkout/cli/build将SDKMAN指向本地安装以进行开发。

虽然不需要使用Micronaut,但Micronaut CLI是创建新服务器应用程序的最快方式。

使用CLI,您可以在Groovy、Java或Kotlin(缺省为Java)中创建新的Micronaut应用程序。

以下命令使用带有Gradle版本的Java创建一个新的";Hello World";服务器应用程序:

如果您希望创建基于Maven的构建,则可以提供--build maven。

前面的命令将在一个名为hello-world的目录中创建一个新的Java应用程序,其中包含Gradle版本。该应用程序可以使用./gradlew run:

$./gradlew运行>;任务:运行[Main]info io.micronaut.runtime.Micronaut-启动在972ms内完成。正在运行的服务器:http://localhost:28933。

默认情况下,Micronaut HTTP服务器配置为在端口8080上运行。有关更多选项,请参阅用户指南中的在特定端口上运行服务器一节。

为了创建响应Hello World的服务,您首先需要一个控制器。以下是控制器的示例:

import io.micronaut.http.MediaType;import io.micronaut.http.annotation.Controller;import io.micronaut.http.annotation.Get;@Controller(";/hello";)(1)公共类HelloController{@Get(Products=MediaType.TEXT_PLAN)(2)公共字符串索引(){Return";Hello World;(3)}}。

import io.micronaut.http.MediaTypeimport io.micronaut.http.注解.Controllerimport io.micronaut.http.annotation.Get@Controller(';/hello';)(1)class HelloController{@GET(Products=MediaType.TEXT_PLAN)(2)String index(){';Hello World';(3)}}

import io.micronaut.http.MediaTypeimport io.micronaut.http.注解.Controllerimport io.micronaut.http.annotation.Get@Controller(";/hello";)(1)class HelloController{@GET(Products=[MediaType.TEXT_PLAN])(2)FUN index():String{Return";Hello World";(3)}}。

该类被定义为控制器,并将@Controller注释映射到路径/hello。

@GET注释用于将索引方法映射到使用HTTP GET的所有请求。

如果您使用的是Java,请将前面的f。

..