泽兴芝士网

一站式 IT 编程学习资源平台

为什么Micronaut比SpringBoot启动更快,占用内存更少(1)

  1. 什么是 Micronaut

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

别告诉你没有听说过Grails ?

虽然 Micronaut 包含了一些与现有框架(如 Spring)相似的特性,但它也具备一些使其与众不同的新功能。Micronaut 支持 Java、Groovy 和 Kotlin,为构建应用程序提供了多种选择。

2. 主要特性

Micronaut最令人兴奋的特性之一是它的编译时依赖注入机制。大多数框架在运行时使用反射和代理来进行依赖注入,而 Micronaut 则在编译时构建其依赖注入数据。这样可以实现更快的应用启动速度和更小的内存占用。

另一个特点是它对响应式编程的原生支持,适用于客户端和服务器。开发者可以自行选择响应式实现方式,Micronaut同时支持RxJava和 Project Reactor。

Micronaut还具备多个特性,使其非常适合开发云原生应用。它支持多种服务发现工具,如 Eureka 和 Consul,也兼容不同的分布式追踪系统,如 Zipkin 和 Jaeger。

3. 入门指南

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

sdk install micronaut 1.0.0.RC2


如果你没有用过SDKMAN,关注我,后面的文章会带着大家学习该工具


该命令会安装我们构建、测试和部署Micronaut应用所需的所有二进制文件。它还提供了 Micronaut CLI 工具,方便我们快速启动新项目。

这些二进制文件也可以在 GitHub 上获取。

在接下来的章节中,我们将介绍该框架的一些特性。

4. 依赖注入

如前所述,Micronaut 在编译时处理依赖注入,这一点区别于大多数 IoC 容器。

不过,它仍然完全支持 JSR-330 注解,因此使用 Bean 的方式与其他 IoC 框架类似。

要将一个 Bean 自动注入到代码中,我们可以使用 @Inject:

@Inject
private EmployeeService service;

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

默认情况下,所有Bean的作用域为原型(prototype)。我们可以使用 @Singleton 快速创建单例Bean。如果有多个类实现了相同的Bean接口,可以使用 @Primary 来解决冲突:

@Primary
@Singleton
public class BlueCar implements Car {}

@Requires 注解可用于当某些 Bean 是可选的,或只有在满足特定条件时才进行自动注入的场景。

在这方面,它的行为与 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. 构建 HTTP 服务器

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

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

这将在名为 hello-world-server 的目录中创建一个使用 Maven 构建的新 Java 项目。在该目录中,我们可以找到应用源码、Maven的POM文件以及项目所需的其他文件。

默认生成的应用非常简单:

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

5.1. 阻塞式 HTTP

当前这个应用本身功能很有限。我们来添加一个包含两个url的控制器。它们都返回问候语,一个使用 GET 请求,另一个使用 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. 响应式 IO

默认情况下,Micronaut 使用传统的阻塞式 I/O 来实现这些controller。不过,只需更改返回类型为任意响应式的非阻塞类型,就可以快速实现非阻塞controller。

例如,使用 RxJava 时可以返回 Observable;而使用 Reactor 时,可以返回 Mono 或 Flux 类型:

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

无论是阻塞还是非阻塞端点,Micronaut 底层使用的 HTTP 服务器都是 Netty。

通常,请求由启动时创建的主 I/O 线程池处理,因此是阻塞的。

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

未完待续,关注我,下一章节跟着我一起学习客户端构建和MicronautCLL。


我是一名有十年以上经验的Java老码农,曾经沉迷于代码的世界,也曾在传统业务系统中摸爬滚打。但时代在变,AI 正在重塑技术格局。我不想被浪潮甩在身后,所以选择重新出发,走上 AI 学习与转型的旅程。

这个公众号,记录的不是鸡汤,也不是“割韭菜”的教程,而是我一个程序员真实的思考、学习、实战经验,以及从困惑到突破的全过程。

如果你也是在技术瓶颈中思考转型、想了解 AI 如何与传统开发结合、又或仅仅想看一个普通工程师的进化之路,欢迎关注,一起探索,一起成长。

关注我 和我一起,紧跟着AI的步伐,不被时代抛弃。

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言