带你认识一下Micronaut框架以及简单使用

2021-08-13 15:08:13 浏览数 (6422)

什么是Micronaut

Micronaut是一个基于JVM的框架,用于构建轻量级、模块化的应用程序。Micronaut是由创建Grails的同一家公司OCI开发的最新框架,旨在使创建微服务变得快速和简单。

虽然Micronaut包含一些类似于Spring等现有框架的特性,但它也有一些新特性使它与众不同。通过对Java、Groovy和Kotlin的支持,它提供了多种创建应用程序的方法。

主要特点

Micronaut最令人兴奋的特性之一是它的编译时依赖注入机制。大多数框架使用反射和代理在运行时执行依赖注入。然而,Micronaut在编译时构建其依赖注入数据。结果是更快的应用程序启动和更小的内存占用。

另一个特性是它对客户端和服务器的反应式编程的一流支持。由于RxJava和projectreactor都受支持,所以特定的反应式实现的选择权留给了开发人员。

Micronaut还具有一些特性,使其成为开发云本地应用程序的优秀框架。它支持多种服务发现工具,如Eureka和consur,还可以与不同的分布式跟踪系统(如Zipkin和Jaeger)一起使用。

它还提供了对创建AWS lambda函数的支持,使得创建Serverless无服务器应用程序变得容易。

入门

最简单的入门方法是使用SDKMAN:

> sdk install micronaut 1.0.0.RC2

这将安装我们构建、测试和部署Micronaut应用程序所需的所有二进制文件。它还提供Micronaut CLI工具,使我们能够轻松地启动新项目。

在下面的部分中,我们将介绍框架的一些特性。

依赖注入

如前所述,Micronaut在编译时处理依赖注入,这与大多数IoC容器不同。

但是,它仍然完全支持JSR-330注释,因此使用bean与其他IoC框架类似。

为了将bean自动连接到我们的代码中,我们使用@Inject:

@Inject
private EmployeeService service;

@Inject注释的工作方式与@Autowired类似,可以用于字段、方法、构造函数和参数。

默认情况下,所有bean的作用域都是一个原型。我们可以使用@singleton快速创建单例bean。如果多个类实现相同的bean接口,@Primary可以用来消除它们之间的冲突:

@Primary
@Singleton
public class BlueCar implements Car {}

当bean是可选的时,可以使用@Requires注释,或者仅当满足某些条件时才执行自动连接。

在这方面,它的行为非常类似于Spring Boot@Conditional注解:

@Singleton
@Requires(beans = DataSource.class)
@Requires(property = "enabled")
@Requires(missingBeans = EmployeeService)
@Requires(sdk = Sdk.JAVA, value = "1.8")
public class JdbcEmployeeService implements EmployeeService {}

构建HTTP服务器

现在让我们看看如何创建一个简单的HTTP服务器应用程序。首先,我们将使用SDKMAN创建一个项目:

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

这将在名为helloworld server的目录中使用Maven创建一个新的Java项目。在这个目录中,我们将找到主要的应用程序源代码、Maven POM文件和项目的其他支持文件。

默认应用程序非常简单:

public class ServerApplication {
    public static void main(String[] args) {
        Micronaut.run(ServerApplication.class);
    }
}

阻塞HTTP

就其本身而言,这个应用程序不会有太大的作用。让我们添加一个具有两个端点的控制器。两者都将返回问候语,但其中一个将使用GET HTTP动词,另一个将使用POST:

@Controller("/greet")
public class GreetController {

    @Inject
    private GreetingService greetingService;

    @Get("/{name}")
    public String greet(String name) {
        return greetingService.getGreeting() + name;
    }

    @Post(value = "/{name}", consumes = MediaType.TEXT_PLAIN)
    public String setGreeting(@Body String name) {
        return greetingService.getGreeting() + name;
    }
}

反应式IO

默认情况下,Micronaut将使用传统的阻塞I/O实现这些端点。但是,我们可以通过将返回类型更改为任何反应性非阻塞类型来快速实现非阻塞端点。

例如,对于RxJava,我们可以使用Observable。同样,在使用Reactor时,我们可以返回Mono或Flux数据类型:

@Get("/{name}")
public Mono<String> greet(String name) {
    return Mono.just(greetingService.getGreeting() + name);
}

对于阻塞和非阻塞端点,Netty都是用于处理HTTP请求的底层服务器。

通常,请求在启动时创建的主I/O线程池中处理,使它们阻塞。

但是,当从控制器端点返回非阻塞数据类型时,Micronaut使用Netty事件循环线程,使整个请求成为非阻塞的。

构建HTTP客户端

现在让我们构建一个客户机来使用刚刚创建的端点。Micronaut提供两种创建HTTP客户端的方法:

  • 声明性HTTP客户端
  • 可编程的HTTP客户机

声明性HTTP客户端

第一种也是最快的创建方法是使用声明性方法:

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

注意我们没有实现任何代码来调用我们的服务。相反,Micronaut理解如何从我们提供的方法签名和注释调用服务。

为了测试这个客户机,我们可以创建一个JUnit测试,它使用嵌入式服务器API来运行我们服务器的嵌入式实例:

public class GreetingClientTest {
    private EmbeddedServer server;
    private GreetingClient client;

    @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"), "Hello Mike");
    }
}

编程HTTP客户端

如果我们需要对其行为和实现进行更多的控制,我们还可以选择编写更传统的客户端:

@Singleton
public class ConcreteGreetingClient {
   private RxHttpClient httpClient;

   public ConcreteGreetingClient(@Client("/") RxHttpClient httpClient) {
      this.httpClient = httpClient;
   }

   public String greet(String name) {
      HttpRequest<String> req = HttpRequest.GET("/greet/" + name);
      return httpClient.retrieve(req).blockingFirst();
   }

   public Single<String> greetAsync(String name) {
      HttpRequest<String> req = HttpRequest.GET("/async/greet/" + name);
      return httpClient.retrieve(req).first("An error as occurred");
   }
}

默认的HTTP客户机使用RxJava,因此可以轻松地处理阻塞或非阻塞调用。

Micronaut客户端

当我们使用Micronaut CLI工具创建示例项目时,我们已经看到了它的实际应用。

在我们的例子中,我们创建了一个独立的应用程序,但它还有其他一些功能。

联合项目

在Micronaut中,联合只是一组位于同一目录下的独立应用程序。通过使用联邦,我们可以轻松地将它们管理在一起,并确保它们获得相同的默认值和设置。

当我们使用CLI工具生成联合体时,它采用与create app命令相同的参数。它将创建一个顶级的项目结构,每个独立的应用程序将在其子目录中创建。

特征

创建独立应用程序或联合时,我们可以决定应用程序需要哪些功能。这有助于确保项目中包含最小的依赖项集。

我们使用-features参数指定特性,并提供以逗号分隔的特性名称列表。

我们可以通过运行以下命令找到可用功能的列表:

> mn profile-info service

Provided Features:
--------------------
* annotation-api - Adds Java annotation API
* config-consul - Adds support for Distributed Configuration with Consul
* discovery-consul - Adds support for Service Discovery with Consul
* discovery-eureka - Adds support for Service Discovery with Eureka
* groovy - Creates a Groovy application
[...] More features available

现有项目

我们还可以使用CLI工具来修改现有的项目。使我们能够创建bean、客户机、控制器等等。当我们在现有项目中运行mn命令时,将有一组新的命令可用:

> mn help
| Command Name         Command Description
-----------------------------------------------
create-bean            Creates a singleton bean
create-client          Creates a client interface
create-controller      Creates a controller and associated test
create-job             Creates a job with scheduled method

小结

在对Micronaut的简要介绍中,我们看到了构建阻塞和非阻塞HTTP服务器和客户端是多么容易。此外,我们还探讨了它的CLI的一些特性。

但这只是它提供的功能的一小部分。它还完全支持serverless功能、服务发现、分布式跟踪、监视和度量、分布式配置等等。

尽管它的许多特性都是从Grails和Spring等现有框架中派生出来的,但它也有许多独特的特性帮助它脱颖而出。

一如既往,我们可以在GitHub repo中找到上面的示例代码:https://github.com/eugenp/tutorials/tree/master/micronaut

到此本篇关于Java的Micronaut框架的介绍以及简单使用的内容就介绍完了,想要了解更多Java框架内容,请多多关注W3Cschool其他相关内容的文章。