Introduction to Micronaut Framework – Micronaut框架介绍

最后修改: 2018年 7月 19日

中文/混合/英文(键盘快捷键:t)

1. What Is Micronaut

1.什么是Micronaut

Micronaut is a JVM-based framework for building lightweight, modular applications. Developed by OCI, the same company that created Grails, Micronaut is the latest framework designed to make creating microservices quick and easy.

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

While Micronaut contains some features that are similar to existing frameworks like Spring, it also has some new features that set it apart. And with support for Java, Groovy, and Kotlin, it offers a variety of ways to create applications.

虽然Micronaut包含一些与Spring等现有框架相似的功能,但它也有一些新的功能使其与众不同。而且由于支持Java、Groovy和Kotlin,它提供了多种创建应用程序的方式。

2. Main Features

2.主要特点

One of the most exciting features of Micronaut is its compile time dependency injection mechanism. Most frameworks use reflection and proxies to perform dependency injection at runtime. Micronaut, however, builds its dependency injection data at compile time. The result is faster application startup and smaller memory footprints.

Micronaut最令人兴奋的功能之一是它的编译时依赖注入机制。大多数框架在运行时使用反射和代理来执行依赖注入。Micronaut却在编译时建立了它的依赖注入数据。其结果是更快的应用程序启动和更小的内存足迹。

Another feature is its first class support for reactive programming, for both clients and servers. The choice of a specific reactive implementation is left to the developer as both RxJava and Project Reactor are supported.

另一个特点是它对客户端和服务器的反应式编程的一流支持。由于RxJava和Project Reactor都被支持,所以具体的反应式实现的选择权留给了开发者。

Micronaut also has several features that make it an excellent framework for developing cloud-native applications. It supports multiple service discovery tools such as Eureka and Consul, and also works with different distributed tracing systems such as Zipkin and Jaeger.

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

It also provides support for creating AWS lambda functions, making it easy to create serverless applications.

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

3. Getting Started

3.入门

The easiest way to get started is using SDKMAN:

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

> sdk install micronaut 1.0.0.RC2

This installs all the binary files we’ll need to build, test, and deploy Micronaut applications. It also provides the Micronaut CLI tool, which lets us easily start new projects.

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

The binary artifacts are also available on Sonatype and GitHub.

二进制工件也可以在SonatypeGitHub上获得。

In the following sections we’ll look at some features of the framework.

在下面的章节中,我们将看一下这个框架的一些特点。

4. Dependency Injection

4.依赖性注入

As mentioned earlier, Micronaut handles dependency injection at compile time, which is different than most IoC containers.

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

However, it still fully supports JSR-330 annotations so working with beans is similar to other IoC frameworks.

然而,它仍然完全支持JSR-330注解,因此与Bean的工作类似于其他IoC框架。

To autowire a bean into our code, we use @Inject:

为了在我们的代码中自动连接一个bean,我们使用@Inject:

@Inject
private EmployeeService service;

The @Inject annotation works just like @Autowired and can be used on fields, methods, constructors, and parameters.

@Inject 注解的作用与@Autowired一样,可以用于字段、方法、构造函数和参数。

By default, all beans are scoped as a prototype. We can quickly create singleton beans using @Singleton. If multiple classes implement the same bean interface, @Primary can be used to deconflict them:

默认情况下,所有的Bean都是以原型为范围的。我们可以使用@Singleton来快速创建单子Bean。如果多个类实现了相同的Bean接口,可以使用@Primary来解除它们之间的冲突。

@Primary
@Singleton
public class BlueCar implements Car {}

The @Requires annotation can be used when beans are optional, or to only perform autowiring when certain conditions are met.

@Requires注解可以在Bean是可选的时候使用,或者只在满足某些条件时执行自动布线。

In this regard, it behaves much like the Spring Boot @Conditional annotations:

在这方面,它的行为很像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 {}

5. Building an HTTP Server

5.建立一个HTTP服务器

Now let’s look at creating a simple HTTP server application. To start, we’ll use SDKMAN to create a project:

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

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

This will create a new Java project using Maven in a directory named hello-world-server. Inside this directory, we’ll find our main application source code, Maven POM file, and other support files for the project.

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

The default application that is very simple:

默认的应用程序,非常简单。

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

5.1. Blocking HTTP

5.1.封锁HTTP

On its own, this application won’t do much. Let’s add a controller that has two endpoints. Both will return a greeting, but one will use the GET HTTP verb, and the other will use POST:

就其本身而言,这个应用程序不会做什么。让我们添加一个控制器,它有两个端点。两者都将返回一个问候语,但其中一个将使用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;
    }
}

5.2. Reactive IO

5.2.反应式IO

By default, Micronaut will implement these endpoints using traditional blocking I/O. However, we can quickly implement non-blocking endpoints by merely changing the return type to any reactive non-blocking type.

默认情况下,Micronaut将使用传统的阻塞式I/O实现这些端点。然而,我们可以快速实现非阻塞式端点,只需将返回类型改为任何反应式非阻塞类型

For example, with RxJava we can use Observable. Likewise, when using Reactor, we can return Mono or Flux data types:

例如,在RxJava中我们可以使用Observable。同样地,在使用Reactor时,我们可以返回MonoFlux数据类型。

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

For both blocking and non-blocking endpoints, Netty is the underlying server used to handle HTTP requests.

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

Normally, the requests are handled on the main I/O thread pool that is created at startup, making them block.

通常情况下,这些请求是在启动时创建的主I/O线程池上处理的,这使得它们被阻塞。

However, when a non-blocking data type is returned from a controller endpoint, Micronaut uses the Netty event loop thread, making the whole request non-blocking.

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

6. Building an HTTP Client

6.建立一个HTTP客户端

Now let’s build a client to consume the endpoints we just created. Micronaut provides two ways of creating HTTP clients:

现在让我们建立一个客户端来消费我们刚刚创建的端点。Micronaut提供了两种创建HTTP客户端的方法。

  • A declarative HTTP Client
  • A programmatic HTTP Client

6.1. Declarative HTTP Client

6.1.声明式HTTP客户端

The first and quickest way to create is using a declarative approach:

第一个也是最快速的创建方式是使用声明式方法。

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

Notice how we don’t implement any code to call our service. Instead, Micronaut understands how to call the service from the method signature and annotations we have provided.

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

To test this client, we can create a JUnit test that uses the embedded server API to run an embedded instance of our server:

为了测试这个客户端,我们可以创建一个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");
    }
}

6.2. Programmatic HTTP Client

6.2.程序化的HTTP客户端

We also have the option of writing a more traditional client if we need more control over its behavior and implementation:

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

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

The default HTTP client uses RxJava, so can easily work with blocking or non-blocking calls.

默认的HTTP客户端使用RxJava,所以可以很容易地与阻塞或非阻塞的调用一起工作。

7. Micronaut CLI

7.Micronaut CLI

We’ve already seen the Micronaut CLI tool in action above when we used it to create our sample project.

在上面我们已经看到了Micronaut CLI工具的作用,我们用它来创建我们的样本项目。

In our case, we created a standalone application, but it has several other capabilities as well.

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

7.1. Federation Projects

7.1.联邦项目

In Micronaut, a federation is just a group of standalone applications that live under the same directory. By using federations, we can easily manage them together and ensure they get the same defaults and settings.

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

When we use the CLI tool to generate a federation, it takes all the same arguments as the create-app command. It will create a top-level project structure, and each standalone app will be created in its sub-directory from there.

当我们使用CLI工具来生成一个联盟时,它接受所有与create-app命令相同的参数。它将创建一个顶层的项目结构,每个独立的应用程序将在其子目录中创建。

7.2. Features

7.2.特征

When creating a standalone application or federation, we can decide which features our app needs. This helps ensure the minimal set of dependencies is included in the project.

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

We specify features using the -features argument and supplying a comma-separated list of feature names.

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

We can find a list of available features by running the following command:

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

> 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

7.3. Existing Projects

7.3.现有的项目

We can also use the CLI tool to modify existing projects. Enabling us to create beans, clients, controllers, and more. When we run the mn command from inside an existing project, we’ll have a new set of commands available:

我们还可以使用CLI工具来修改现有的项目。使我们能够创建bean、client、controllers等。当我们在现有项目中运行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

8. Conclusion

8.结语

In this brief introduction to Micronaut, we’ve seen how easy it is to build both blocking and non-blocking HTTP servers and clients. Also, we explored some features of its CLI.

在这个关于Micronaut的简单介绍中,我们已经看到了它是多么容易建立阻塞和非阻塞的HTTP服务器和客户端。此外,我们还探索了它的CLI的一些功能。

But this is just a small taste of the features it offers. There is also full support for serverless functions, service discovery, distributed tracing, monitoring and metrics, a distributed configuration, and much more.

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

And while many of its features are derived from existing frameworks such as Grails and Spring, it also has plenty of unique features that help it stand out on its own.

虽然它的许多功能都来自于现有的框架,如Grails和Spring,但它也有很多独特的功能,帮助它自己脱颖而出。

As always, we can find the samples code above in our GitHub repo.

一如既往,我们可以在我们的GitHub repo中找到上述样本代码。