1. 什么是 Micronaut

Micronaut 是一个基于 JVM 的轻量级、模块化应用开发框架。由 OCI 公司(也是 Grails 框架的开发者)打造,Micronaut 的设计目标就是让微服务开发变得更快、更简单

虽然它在某些功能上与 Spring 等主流框架有相似之处,但其核心机制上的创新让它脱颖而出。支持 Java、Groovy 和 Kotlin 多语言开发,灵活性高,适合现代云原生场景。

2. 核心特性

✅ 编译时依赖注入(Compile-time DI)

这是 Micronaut 最亮眼的特性之一。大多数框架(如 Spring)依赖运行时反射和动态代理实现 IoC,而 Micronaut 在编译阶段就完成依赖关系的解析和注入代码生成。这意味着:

  • ❌ 无运行时反射开销
  • ✅ 启动速度极快(毫秒级)
  • ✅ 内存占用显著降低
  • ✅ 更适合 Serverless、函数计算等资源敏感场景

✅ 原生响应式编程支持

Micronaut 对响应式编程提供一级公民支持,无论是客户端还是服务端,都能无缝集成:

  • 支持 RxJava 2/3
  • 支持 Project Reactor(Mono/Flux)
  • 控制器方法直接返回响应式类型即可启用非阻塞 IO

✅ 云原生能力开箱即用

  • 服务发现:支持 Eureka、Consul
  • 分布式追踪:集成 Zipkin、Jaeger
  • 配置中心:支持 Consul、Vault 等
  • Serverless:原生支持 AWS Lambda,轻松构建无服务器应用

这些不是插件,而是框架级能力,配置简单,踩坑少。

3. 快速开始

推荐使用 SDKMAN 安装 Micronaut CLI:

sdk install micronaut 1.0.0.RC2

安装后即可使用 mn 命令行工具创建、构建和管理项目。二进制包也托管在 SonatypeGitHub

接下来我们通过实际代码体验核心功能。

4. 依赖注入机制

Micronaut 虽然采用编译时 DI,但 完全兼容 JSR-330 注解标准,开发者无需学习新语法,迁移成本低。

常用注解用法

@Inject
private EmployeeService service;
  • @Inject:等价于 Spring 的 @Autowired,可用于字段、方法、构造函数和参数。
  • 默认所有 Bean 为原型(prototype)作用域。
  • 使用 @Singleton 创建单例 Bean。

解决 Bean 冲突

当多个实现类实现同一接口时,可用 @Primary 指定优先使用哪个:

@Primary
@Singleton
public class BlueCar implements Car {}

条件化 Bean 加载

类似 Spring Boot 的 @Conditional,Micronaut 提供 @Requires 实现条件化加载:

@Singleton
@Requires(beans = DataSource.class)           // 存在指定 Bean 时才加载
@Requires(property = "enabled")               // 存在指定配置项
@Requires(missingBeans = EmployeeService)     // 指定 Bean 不存在时
@Requires(sdk = Sdk.JAVA, value = "1.8")      // 指定 JDK 版本
public class JdbcEmployeeService implements EmployeeService {}

✅ 编译时校验,避免运行时条件判断带来的性能损耗。

5. 构建 HTTP 服务

使用 CLI 创建 Maven 项目:

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

生成的主类非常简洁:

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

5.1 阻塞式 HTTP 接口

添加控制器实现两个接口:

@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;
    }
}
  • @Get@Post 定义 HTTP 方法
  • 路径变量 {name} 自动绑定到参数
  • @Body 显式声明请求体参数

⚠️ 默认使用阻塞 IO,请求在主线程池处理。

5.2 响应式非阻塞 IO

只需修改返回类型为响应式类型,即可切换为非阻塞模式:

@Get("/{name}")
public Mono<String> greet(String name) {
    return Mono.just(greetingService.getGreeting() + name);
}
  • 返回 Mono(Reactor)或 Observable(RxJava)即可启用非阻塞
  • 底层使用 Netty 作为 Web 服务器
  • 非阻塞接口由 Netty Event Loop 线程处理,避免线程阻塞

✅ 简单粗暴,零配置切换响应式模型。

6. 构建 HTTP 客户端

Micronaut 提供两种方式创建 HTTP 客户端,满足不同场景需求。

6.1 声明式客户端(推荐)

接口即契约,无需实现类:

@Client("/greet")
public interface GreetingClient {
    @Get("/{name}")
    String greet(String name);
}
  • @Client 指定基础路径
  • 方法签名 + 注解自动映射为 HTTP 请求
  • 编译时生成代理实现,无反射开销

测试示例

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");
    }
}
  • 使用 EmbeddedServer 启动内嵌服务
  • 直接注入客户端进行测试,集成测试写起来非常爽

6.2 编程式客户端

需要精细控制时使用:

@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 has occurred");
   }
}
  • RxHttpClient 默认基于 RxJava,支持同步/异步调用
  • 适合复杂请求逻辑或动态 URL 场景

7. Micronaut CLI 工具

mn 不只是项目生成器,更是生产力工具。

7.1 联合项目(Federation Projects)

Federation 是一组共用父目录的独立应用集合。

mn create-federation my-microservices --features=security,jdbc
  • 自动生成多模块结构
  • 统一配置依赖和特性
  • 适合微服务集群快速搭建

7.2 特性(Features)机制

创建项目时可通过 -features 指定所需能力,避免引入无用依赖:

mn create-app myapp -features=discovery-eureka,config-consul,reactive

常用特性:

mn profile-info service

Provided Features:
--------------------
* annotation-api     - 添加 Java 注解 API
* config-consul      - 支持 Consul 配置中心
* discovery-consul   - 支持 Consul 服务发现
* discovery-eureka   - 支持 Eureka 服务发现
* groovy             - 创建 Groovy 项目
[...] 更多特性可用

✅ 真正做到按需引入,项目轻量化。

7.3 管理现有项目

在已有项目根目录执行 mn,可动态添加组件:

mn create-controller Greet
mn create-client PaymentClient
mn create-bean AnalyticsService

支持命令:

命令 说明
create-bean 创建单例 Bean
create-client 创建客户端接口
create-controller 创建控制器及测试类
create-job 创建定时任务

开发中随时生成代码,效率拉满。

8. 总结

本文带你快速体验了 Micronaut 的核心能力:

  • ✅ 编译时 DI:极致启动速度与低内存占用
  • ✅ 响应式优先:轻松构建非阻塞服务
  • ✅ 云原生集成:服务发现、分布式追踪等开箱即用
  • ✅ 强大 CLI:项目生成与代码管理一体化

虽然借鉴了 Spring 和 Grails 的优秀设计,但 Micronaut 在架构层面的创新(尤其是编译时处理)让它在 Serverless、微服务等场景具备显著优势。

所有示例代码已上传至 GitHub:

https://github.com/techblog-examples/micronaut-tutorial


原始标题:Introduction to Micronaut Framework