1. 概述
本教程將比較 Micronaut 和 Spring Boot。Spring Boot 是流行的 Spring 框架的一部分,用於快速啓動 Spring 應用。Micronaut 是一個基於 JVM 的框架,旨在解決 Spring/Spring Boot 的一些弱點。
我們將從幾個方面比較這兩個框架。首先,我們將比較創建新應用程序的便捷性、語言支持以及其他配置選項。然後,我們將查看兩個簡單的 REST 應用程序。最後,我們將比較代碼並衡量性能差異。
2. 功能
在以下部分,我們將詳細介紹這兩個框架中的各項功能。
2.1. 環境搭建
首先,我們將比較在兩個框架中啓動新應用程序的便捷程度。
Micronaut 和 Spring Boot 均提供多種便捷的方法來創建新應用程序。例如,我們可以使用命令行界面在兩個框架中創建新應用程序。 此外,我們還可以使用 Spring Boot 的 Spring Initializr 或 Micronaut 提供的 Launch 工具。
在 IDE 支持方面,我們可以使用 Spring Boot 插件,適用於大多數流行的 IDE,包括 Eclipse Spring Tools Suite。 如果我們使用 IntelliJ,則我們有 Micronaut 插件可用。
2.2 語言支持
轉向語言支持時,我們會發現它在 Spring Boot 和 Micronaut 之間幾乎完全相同。對於這兩個框架,我們可以選擇使用 Java、Groovy 或 Kotlin。如果選擇 Java,這兩個框架都支持 Java 8、11 和 17 版本。此外,我們還可以使用 Gradle 或 Maven 與這兩個框架一起使用。
2.3. Servlet 容器
使用 Spring Boot,我們的應用程序默認使用 Tomcat。但是,我們也可以配置 Spring Boot 使用 Jetty 或 Undertow。
我們的 Micronaut 應用程序默認在基於 Netty 的 HTTP 服務器上運行。但是,我們可以選擇將應用程序切換到 Tomcat、Jetty 或 Undertow 上運行。
2.4. 屬性配置
對於 Spring Boot,我們可以通過 <em >application.properties</em > 或 <em >application.yml</em > 定義我們的屬性。我們可以使用 <em >application-{env}.properties</em > 約定來為不同的環境提供不同的屬性。 此外,我們還可以使用系統屬性、環境變量或 JNDI 屬性覆蓋應用程序文件中提供的屬性。
對於 Micronaut,我們可以使用 <em >application.properties</em >、<em >application.yml</em > 和 `application.json> 作為我們的屬性文件。 我們可以也使用相同的約定來提供特定環境的屬性文件。 如果我們需要覆蓋任何屬性,我們可以使用系統屬性或環境變量。
2.5. 消息支持
如果使用 Spring Boot 中的消息隊列,我們可選擇 Active MQ、Artemis、Rabbit MQ 和 Apache Kafka。
在 Micronaut 方面,我們可選擇 Apache Kafka、Rabbit MQ 和 Nats.io。
2.6. 安全性
Spring Boot 提供五種授權策略:基本授權、表單登錄、JWT、SAML 和 LDAP。如果使用 Micronaut,則我們擁有相同的選項,但不支持 SAML。
兩個框架都提供 OAuth2 支持。
在實際應用安全性方面,兩個框架都允許我們使用註解來保護方法。
2.7. 運維與監控
兩個框架都賦予我們監控應用程序各種指標和統計數據的能力。我們可以在兩個框架中定義自定義端點。 此外,我們還可以配置兩個框架中的端點安全設置。
然而,Spring Boot Actuator 提供了比 Micronaut 更多的內置端點。
2.8. 模板語言
我們可以使用這兩個框架構建完整的全棧應用程序,利用提供的模板語言來渲染前端。
對於 Spring Boot,我們的選擇包括 Thymeleaf、Apache Freemarker、Mustache 和 Groovy。 儘管使用 JSP 受到不推薦,但也可以選擇使用。
在 Micronaut 中,我們有更多選項可供選擇,包括 Thymeleaf、Handlebars、Apache Velocity、Apache Freemarker、Rocker、Soy/Closure 和 Pebbles。
2.9. 雲支持
Spring Boot 應用程序依賴第三方庫來實現許多雲特定功能。
Micronaut 旨在原生支持雲原生微服務。 Micronaut 將原生處理的雲相關概念包括分佈式配置、服務發現、客户端負載均衡、分佈式追蹤和無服務器函數。
3. 代碼
現在我們已經比較了兩種框架的基本功能,接下來我們將創建和比較兩個應用程序。為了保持簡單,我們將創建一個簡單的 REST API,用於解決基本算術問題。我們的服務層將由一個實際執行數學運算的類組成。我們的控制器類將包含加法、減法、乘法和除法的端點。
在深入研究代碼之前,讓我們考慮 Spring Boot 和 Micronaut 之間的一個重要差異。雖然這兩種框架都提供依賴注入,但它們的方式不同。我們的 Spring Boot 應用程序使用反射和代理在運行時處理依賴注入。相比之下,我們的 Micronaut 應用程序在編譯時構建依賴注入數據。
3.1. Spring Boot 應用
首先,讓我們在我們的 Spring Boot 應用中定義一個名為 ArithmeticService 的類:
@Service
public class ArithmeticService {
public float add(float number1, float number2) {
return number1 + number2;
}
public float subtract(float number1, float number2) {
return number1 - number2;
}
public float multiply(float number1, float number2) {
return number1 * number2;
}
public float divide(float number1, float number2) {
if (number2 == 0) {
throw new IllegalArgumentException("'number2' cannot be zero");
}
return number1 / number2;
}
}接下來,讓我們創建我們的 REST 控制器:
@RestController
@RequestMapping("/math")
public class ArithmeticController {
@Autowired
private ArithmeticService arithmeticService;
@GetMapping("/sum/{number1}/{number2}")
public float getSum(@PathVariable("number1") float number1, @PathVariable("number2") float number2) {
return arithmeticService.add(number1, number2);
}
@GetMapping("/subtract/{number1}/{number2}")
public float getDifference(@PathVariable("number1") float number1, @PathVariable("number2") float number2) {
return arithmeticService.subtract(number1, number2);
}
@GetMapping("/multiply/{number1}/{number2}")
public float getMultiplication(@PathVariable("number1") float number1, @PathVariable("number2") float number2) {
return arithmeticService.multiply(number1, number2);
}
@GetMapping("/divide/{number1}/{number2}")
public float getDivision(@PathVariable("number1") float number1, @PathVariable("number2") float number2) {
return arithmeticService.divide(number1, number2);
}
}我們的控制器擁有用於四種算術函數(加、減、乘、除)的每個端點。
3.2. Micronaut 應用
現在,讓我們創建我們的 Micronaut 應用的服務層:
@Singleton
public class ArithmeticService {
// implementation identical to the Spring Boot service layer
}接下來,我們將為我們的 REST 控制器編寫與 Spring Boot 應用程序相同的四個端點:
@Controller("/math")
public class ArithmeticController {
@Inject
private ArithmeticService arithmeticService;
@Get("/sum/{number1}/{number2}")
public float getSum(float number1, float number2) {
return arithmeticService.add(number1, number2);
}
@Get("/subtract/{number1}/{number2}")
public float getDifference(float number1, float number2) {
return arithmeticService.subtract(number1, number2);
}
@Get("/multiply/{number1}/{number2}")
public float getMultiplication(float number1, float number2) {
return arithmeticService.multiply(number1, number2);
}
@Get("/divide/{number1}/{number2}")
public float getDivision(float number1, float number2) {
return arithmeticService.divide(number1, number2);
}
}我們可以看到我們的非常簡單的示例應用程序之間存在很多相似之處。在差異方面,我們注意到 Micronaut 利用 Java 註解進行注入,而 Spring Boot 則有其自身的註解。此外,我們的 Micronaut REST 端點不需要在傳遞到方法的路徑變量上添加任何特殊註解。
3.3. 基本性能比較
Micronaut 宣稱具有快速啓動時間,讓我們比較這兩種應用程序。
首先,啓動 Spring Boot 應用程序並查看所需時間:
[main] INFO c.b.m.v.s.CompareApplication - Started CompareApplication in 3.179 seconds (JVM running for 4.164)接下來,讓我們看看我們的 Micronaut 應用程序啓動的速度如何:
21:22:49.267 [main] INFO io.micronaut.runtime.Micronaut - Startup completed in 1278ms. Server Running: http://localhost:57535
我們能看到,我們的 Spring Boot 應用程序啓動僅需三秒多一點,在 Micronaut 中則為一秒多一點。
現在我們已經瞭解了啓動時間,讓我們對我們的 API 進行一些測試,然後檢查一些基本的內存統計信息。 我們將在啓動應用程序時使用默認的內存設置。
我們首先將從 Spring Boot 應用程序開始。 首先,讓我們調用四個算術端點,然後調用我們的內存端點:
Initial: 0.25 GB
Used: 0.02 GB
Max: 4.00 GB
Committed: 0.06 GB 接下來,讓我們用我們的 Micronaut 應用程序來完成相同的練習:
Initial: 0.25 GB
Used: 0.01 GB
Max: 4.00 GB
Committed: 0.03 GB在本次有限示例中,我們的兩個應用程序都使用較少的內存,但 Micronaut 的使用量約為 Spring Boot 應用程序的一半。
4. 比較
沒有單一的最佳框架適用於所有應用程序。最佳選擇將取決於應用程序的特定要求以及開發人員的偏好。
但是,以下表格可以提供一些有用的信息,以幫助您做出決定:
| 功能 | Micronaut | Spring Boot |
|---|---|---|
| 大小 | 較小的 JAR 文件 | 較大的 JAR 文件 |
| Actuator | 不支持 | 提供健康檢查、指標等 |
| 構建時間 | 更快 | 更慢 |
| 啓動時間 | 更快的構建時間 | 更慢的構建時間 |
| 性能 | 比 Spring Boot 更好 | 良好 |
| 原生鏡像 | 是 | 默認不支持 |
| 自動配置 | 較少 | 更多 |
| 啓動依賴 | 更少的啓動依賴 | 更多的啓動依賴 |
| 依賴注入 | 基於註解 | 基於屬性 |
| 社區 | 較小的社區 | 較大的社區 |
| 文檔 | 良好的文檔 | 優秀的文檔 |
5. 結論
本文對比了 Spring Boot 和 Micronaut。首先,我們對這兩個框架進行了概述。然後,我們詳細探討了其各項功能並進行了比較。最後,我們對兩個簡單的示例應用程序進行了對比,並分析了它們的啓動時間和內存性能。