From f3b571bf96bfcfae6ea98cd68fda2207fd7638bb Mon Sep 17 00:00:00 2001 From: gewuyou Date: Thu, 24 Jul 2025 08:11:34 +0000 Subject: [PATCH] =?UTF-8?q?feat(plugin)=20=E6=B7=BB=E5=8A=A0=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 58 ++++-- buildSrc/src/main/kotlin/Modules.kt | 14 +- forgeboot-banner/README.md | 57 +++++ forgeboot-cache/README.md | 54 +++++ forgeboot-context/README.md | 103 +++++++++ forgeboot-core/README.md | 40 ++++ forgeboot-demo/README.md | 28 +++ .../forgeboot-plugin-demo/.gitattributes | 3 + .../forgeboot-plugin-demo/.gitignore | 40 ++++ .../forgeboot-plugin-demo/build.gradle.kts | 5 + .../forgeboot-plugin-demo-api/.gitattributes | 3 + .../forgeboot-plugin-demo-api/.gitignore | 40 ++++ .../build.gradle.kts | 7 + .../plugin/demo/api/GreetingProvider.kt | 11 + .../plugin/demo/api/GreetingService.kt | 13 ++ .../forgeboot-plugin-demo-impl/.gitattributes | 3 + .../forgeboot-plugin-demo-impl/.gitignore | 40 ++++ .../build.gradle.kts | 11 + .../plugin/demo/impl/PluginConfig.kt | 21 ++ .../plugin/demo/impl/SimpleGreetingPlugin.kt | 28 +++ .../plugin/demo/impl/SimpleGreetingService.kt | 18 ++ .../src/main/resources/plugin.yml | 4 + .../.gitattributes | 3 + .../forgeboot-plugin-demo-server/.gitignore | 40 ++++ .../build.gradle.kts | 6 + ...ture-6-support-plugin-modules-SNAPSHOT.jar | Bin 0 -> 5088 bytes .../ForgebootPluginDemoServerApplication.kt | 11 + .../demo/server/controller/DemoController.kt | 22 ++ .../server/provider/ServerGreetingProvider.kt | 15 ++ .../src/main/resources/application.yml | 3 + forgeboot-i18n/README.md | 49 +++++ forgeboot-plugin/.gitattributes | 3 + forgeboot-plugin/.gitignore | 40 ++++ forgeboot-plugin/build.gradle.kts | 4 + .../forgeboot-plugin-core/.gitattributes | 3 + .../forgeboot-plugin-core/.gitignore | 40 ++++ .../forgeboot-plugin-core/build.gradle.kts | 9 + .../MappableYamlPluginDescriptorFinder.kt | 85 ++++++++ .../finder/TypedYamlPluginDescriptorFinder.kt | 98 +++++++++ .../core/finder/YamlPluginDescriptorFinder.kt | 77 +++++++ .../core/mapper/YamlPluginDescriptorMapper.kt | 25 +++ .../forgeboot-plugin-spring/.gitattributes | 3 + .../forgeboot-plugin-spring/.gitignore | 37 ++++ .../forgeboot-plugin-spring/build.gradle.kts | 11 + .../plugin/spring/IsolatedSpringPlugin.kt | 48 +++++ .../plugin/spring/MergedSpringPlugin.kt | 54 +++++ .../config/PluginSpringAutoConfiguration.kt | 52 +++++ .../spring/manager/SpringPluginManager.kt | 25 +++ ...ot.autoconfigure.AutoConfiguration.imports | 1 + forgeboot-trace/README.md | 84 ++++++++ forgeboot-webmvc/README.md | 47 +++++ forgeboot-webmvc/dto/README.md | 197 ++++++++++++++++++ forgeboot-webmvc/dto/build.gradle.kts | 1 - .../forgeboot/webmvc/dto/mapper/BaseMapper.kt | 49 ----- .../webmvc/dto/mapper/ConversionMapper.kt | 63 ------ forgeboot-webmvc/spec/README.md | 117 +++++++++++ gradle/libs.versions.toml | 12 +- settings.gradle.kts | 57 ++--- 58 files changed, 1821 insertions(+), 171 deletions(-) create mode 100644 forgeboot-banner/README.md create mode 100644 forgeboot-cache/README.md create mode 100644 forgeboot-context/README.md create mode 100644 forgeboot-core/README.md create mode 100644 forgeboot-demo/README.md create mode 100644 forgeboot-demo/forgeboot-plugin-demo/.gitattributes create mode 100644 forgeboot-demo/forgeboot-plugin-demo/.gitignore create mode 100644 forgeboot-demo/forgeboot-plugin-demo/build.gradle.kts create mode 100644 forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-api/.gitattributes create mode 100644 forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-api/.gitignore create mode 100644 forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-api/build.gradle.kts create mode 100644 forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-api/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/api/GreetingProvider.kt create mode 100644 forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-api/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/api/GreetingService.kt create mode 100644 forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/.gitattributes create mode 100644 forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/.gitignore create mode 100644 forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/build.gradle.kts create mode 100644 forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/impl/PluginConfig.kt create mode 100644 forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/impl/SimpleGreetingPlugin.kt create mode 100644 forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/impl/SimpleGreetingService.kt create mode 100644 forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/src/main/resources/plugin.yml create mode 100644 forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/.gitattributes create mode 100644 forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/.gitignore create mode 100644 forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/build.gradle.kts create mode 100644 forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/plugins/forgeboot-plugin-demo-impl-0.0.7-feature-6-support-plugin-modules-SNAPSHOT.jar create mode 100644 forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/server/ForgebootPluginDemoServerApplication.kt create mode 100644 forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/server/controller/DemoController.kt create mode 100644 forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/server/provider/ServerGreetingProvider.kt create mode 100644 forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/src/main/resources/application.yml create mode 100644 forgeboot-i18n/README.md create mode 100644 forgeboot-plugin/.gitattributes create mode 100644 forgeboot-plugin/.gitignore create mode 100644 forgeboot-plugin/build.gradle.kts create mode 100644 forgeboot-plugin/forgeboot-plugin-core/.gitattributes create mode 100644 forgeboot-plugin/forgeboot-plugin-core/.gitignore create mode 100644 forgeboot-plugin/forgeboot-plugin-core/build.gradle.kts create mode 100644 forgeboot-plugin/forgeboot-plugin-core/src/main/kotlin/com/gewuyou/forgeboot/plugin/core/finder/MappableYamlPluginDescriptorFinder.kt create mode 100644 forgeboot-plugin/forgeboot-plugin-core/src/main/kotlin/com/gewuyou/forgeboot/plugin/core/finder/TypedYamlPluginDescriptorFinder.kt create mode 100644 forgeboot-plugin/forgeboot-plugin-core/src/main/kotlin/com/gewuyou/forgeboot/plugin/core/finder/YamlPluginDescriptorFinder.kt create mode 100644 forgeboot-plugin/forgeboot-plugin-core/src/main/kotlin/com/gewuyou/forgeboot/plugin/core/mapper/YamlPluginDescriptorMapper.kt create mode 100644 forgeboot-plugin/forgeboot-plugin-spring/.gitattributes create mode 100644 forgeboot-plugin/forgeboot-plugin-spring/.gitignore create mode 100644 forgeboot-plugin/forgeboot-plugin-spring/build.gradle.kts create mode 100644 forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/IsolatedSpringPlugin.kt create mode 100644 forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/MergedSpringPlugin.kt create mode 100644 forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/config/PluginSpringAutoConfiguration.kt create mode 100644 forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/manager/SpringPluginManager.kt create mode 100644 forgeboot-plugin/forgeboot-plugin-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 forgeboot-trace/README.md create mode 100644 forgeboot-webmvc/README.md create mode 100644 forgeboot-webmvc/dto/README.md delete mode 100644 forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/mapper/BaseMapper.kt delete mode 100644 forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/mapper/ConversionMapper.kt create mode 100644 forgeboot-webmvc/spec/README.md diff --git a/README.md b/README.md index 998872f..a11c403 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,51 @@ # forgeboot -This project uses [Gradle](https://gradle.org/). -To build and run the application, use the *Gradle* tool window by clicking the Gradle icon in the right-hand toolbar, -or run it directly from the terminal: +多模块 Spring Boot 工具与 Starter 集合 -* Run `./gradlew run` to build and run the application. -* Run `./gradlew build` to only build the application. -* Run `./gradlew check` to run all checks, including tests. -* Run `./gradlew clean` to clean all build outputs. +## 项目概览 -Note the usage of the Gradle Wrapper (`./gradlew`). -This is the suggested way to use Gradle in production projects. +`forgeboot` 是一套面向 Spring Boot 的通用基础库,包含 Banner、缓存、上下文传播、核心工具、国际化、 +调用链追踪、Web MVC 公共组件以及示例模块。旨在帮助团队快速搭建企业级微服务应用。 -[Learn more about the Gradle Wrapper](https://docs.gradle.org/current/userguide/gradle_wrapper.html). +## 模块列表 -[Learn more about Gradle tasks](https://docs.gradle.org/current/userguide/command_line_interface.html#common_tasks). +| 模块名 | 功能简介 | +|-------------------------------------------------|------------------------------| +| forgeboot-banner | 启动横幅 Banner 管理 | +| forgeboot-cache-spring-boot-starter | 缓存自动配置 | +| forgeboot-context-spring-boot-starter | 上下文传播 | +| forgeboot-core | 核心扩展与序列化 | +| forgeboot-i18n-spring-boot-starter | 国际化支持 | +| forgeboot-trace-spring-boot-starter | 分布式调用链追踪 | +| forgeboot-webmvc-spring-boot-starter | Web MVC 公共组件集合 | +| forgeboot-demo | 各模块功能示例 | -This project follows the suggested multi-module setup and consists of the `app` and `utils` subprojects. -The shared build logic was extracted to a convention plugin located in `buildSrc`. +## 快速开始 -This project uses a version catalog (see `gradle/libs.versions.toml`) to declare and version dependencies -and both a build cache and a configuration cache (see `gradle.properties`). \ No newline at end of file +1. 克隆仓库: + ```bash + git clone https://github.com/GeWuYou/forgeboot.git + ``` +2. 构建所有模块: + ```bash + ./gradlew build + ``` +## 构建与发布 + +- **构建** + ```bash + ./gradlew clean build + ``` +- **发布到 Maven 仓库** + 已配置 `maven-publish` 与 `axion-release`,只需执行: + ```bash + ./gradlew release + ``` + +## 贡献指南 + +欢迎提交 Issue 和 PR,共同完善各模块功能与文档。 + +## 许可 + +Apache-2.0 diff --git a/buildSrc/src/main/kotlin/Modules.kt b/buildSrc/src/main/kotlin/Modules.kt index 267e7aa..2a77ae5 100644 --- a/buildSrc/src/main/kotlin/Modules.kt +++ b/buildSrc/src/main/kotlin/Modules.kt @@ -117,7 +117,19 @@ object Modules { "${AUTHORIZE}:forgeboot-security-authorize-autoconfigure" } } + object Plugin { + private const val PLUGIN = ":forgeboot-plugin" + const val CORE = "${PLUGIN}:forgeboot-plugin-core" + const val SPRING = "${PLUGIN}:forgeboot-plugin-spring" + } object Demo{ - const val ROOT = ":forgeboot-demo" + private const val ROOT = ":forgeboot-demo" + object Plugin{ + private const val PLUGIN = "${ROOT}:forgeboot-plugin-demo" + const val API = "${PLUGIN}:forgeboot-plugin-demo-api" + const val IMPL = "${PLUGIN}:forgeboot-plugin-demo-impl" + const val SERVER = "${PLUGIN}:forgeboot-plugin-demo-server" + } + } } \ No newline at end of file diff --git a/forgeboot-banner/README.md b/forgeboot-banner/README.md new file mode 100644 index 0000000..0fa142a --- /dev/null +++ b/forgeboot-banner/README.md @@ -0,0 +1,57 @@ +# forgeboot-banner + +Spring Boot Banner 启动横幅模块 + +## 简介 + +`forgeboot-banner` 提供了一个可插拔的启动横幅(Banner)框架,与 Spring Boot 无缝集成,支持多种横幅渲染策略与配置项。你可以自定义文本、图片或多策略组合的 Banner,在应用启动时显示。 + +## 核心功能 + +- 可通过 `forgeboot.banner.strategy` 配置多种渲染策略(随机、按环境、按时间等)。 +- 支持文本和图片两种 Banner 类型。 +- 提供默认实现,也可自定义 `BannerStrategy` 和 `BannerProvider`。 +- 自动集成 Spring Boot,启动时自动渲染。 + +## 引入依赖 + +使用 Maven: +```xml + + io.github.gewuyou + forgeboot-banner + ${version} + +``` +使用 Gradle: +```groovy +implementation "io.github.gewuyou:forgeboot-banner:${version}" +``` + +## 子模块说明 + +- **forgeboot-banner-api**:核心接口与配置类(`BannerStrategy`, `BannerProvider`, `BannerProperties`)。 +- **forgeboot-banner-impl**:默认实现,包括文件加载、日志输出等逻辑。 +- **forgeboot-banner-launcher**:启动器模块,负责在 Spring Boot 启动阶段触发 Banner 渲染。 + +## 快速开始 + +1. 在 `application.yml` 中启用并配置: + ```yaml + forgeboot: + banner: + enabled: true + strategy: RANDOM + text-location: classpath:/banner.txt + image-location: classpath:/banner.png + ``` +2. 启动应用,查看控制台或日志中的横幅效果。 + +## 构建 +```bash +./gradlew :forgeboot-banner:build +``` + +## 许可 + +Apache-2.0 diff --git a/forgeboot-cache/README.md b/forgeboot-cache/README.md new file mode 100644 index 0000000..85000b6 --- /dev/null +++ b/forgeboot-cache/README.md @@ -0,0 +1,54 @@ +# forgeboot-cache-spring-boot-starter + +Spring Boot 缓存自动配置模块 + +## 简介 + +`forgeboot-cache-spring-boot-starter` 提供基于 Spring Cache 的一站式缓存解决方案,封装了常用的缓存接口、默认实现及自动配置。 + +## 核心功能 + +- **forgeboot-cache-api**:缓存接口定义,统一 `CacheManager`、`Cache` 操作。 +- **forgeboot-cache-impl**:默认内存或 Redis 实现。 +- **forgeboot-cache-autoconfigure**:Spring Boot 自动配置,读取 `forgeboot.cache.*` 配置属性,自动创建 `CacheManager`。 + +## 引入依赖 + +使用 Maven: +```xml + + io.github.gewuyou + forgeboot-cache-spring-boot-starter + ${version} + +``` +使用 Gradle: +```groovy +implementation "io.github.gewuyou:forgeboot-cache-spring-boot-starter:${version}" +``` + +## 配置示例 +```yaml +forgeboot: + cache: + type: redis + redis: + host: localhost + port: 6379 + caffeine: + spec: maximumSize=1000,expireAfterAccess=5m +``` + +## 快速开始 + +1. 添加依赖并配置缓存类型。 +2. 在 Service 方法上使用 `@Cacheable("cacheName")`、`@CacheEvict` 等注解即可生效。 + +## 构建 +```bash +./gradlew :forgeboot-cache:build +``` + +## 许可 + +Apache-2.0 diff --git a/forgeboot-context/README.md b/forgeboot-context/README.md new file mode 100644 index 0000000..fab3464 --- /dev/null +++ b/forgeboot-context/README.md @@ -0,0 +1,103 @@ +# forgeboot-context-spring-boot-starter + +> 🧠 请求上下文感知模块,支持在多线程、Reactor、协程等异步场景中透明传递上下文字段,如 traceId、userId、token 等。 + +--- + +## 🧩 简介 + +`forgeboot-context-spring-boot-starter` 是 ForgeBoot 提供的基础上下文传播模块,旨在解决异步环境下上下文(如用户信息、请求信息)无法传递的问题。 + +支持多执行模型(ThreadLocal、Reactor Context、Kotlin Coroutine Context)无缝上下文共享,并通过统一接口抽象、自动装配、可扩展的字段注入机制,提升服务内的数据一致性与可维护性。 + +--- + +## ✨ 核心功能 + +- ✅ 支持上下文字段自动注入与解析(Header、MDC、自定义) +- ✅ 支持多执行模型(线程 / 协程 / Reactor)上下文透明传递 +- ✅ 提供统一 `ContextHolder` 访问入口 +- ✅ 提供字段注册器与注入策略 SPI 扩展 +- ✅ 支持 Spring Web(Servlet)、WebFlux、Feign、RestTemplate 等组件 +- ✅ 与 trace 模块无缝集成,自动传播 traceId/requestId + +--- + +## 📦 引入依赖 + +使用 Maven: + +```xml + + io.github.gewuyou + forgeboot-context-spring-boot-starter + ${version} + +``` + +使用 Gradle: + +```groovy +implementation "io.github.gewuyou:forgeboot-context-spring-boot-starter:${version}" +``` + +--- + +## 🚀 快速开始 + +### ✅ 基础使用 + +```kotlin +@RestController +class DemoController(private val contextHolder: ContextHolder) { + @GetMapping("/demo") + fun demo(): String { + val traceId = contextHolder.get("traceId") + return "traceId: $traceId" + } +} +``` + +--- + +## 🔌 可扩展点 + +你可以通过实现以下接口来自定义字段注入行为: + +- `ContextProcessor`:用于从请求中提取字段 +- `ContextFieldContributor`:用于注册要注入的上下文字段 + +示例: + +```kotlin +@Component +class CustomContextFieldContributor : ContextFieldContributor { + override fun contribute(registry: FieldRegistry) { + registry.register("tenantId", Scope.THREAD_LOCAL) + } +} +``` + +--- + +## ⚙️ 构建方式 + +使用 Gradle 命令进行构建发布: + +```bash +./gradlew :forgeboot-context:build +``` + +--- + +## 📄 许可 + +本项目采用 [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) 开源协议。 + +--- + +## 📬 联系作者 + +由 [@gewuyou](https://github.com/gewuyou) 维护。 + +欢迎提交 Issue 或 PR 改进本模块! diff --git a/forgeboot-core/README.md b/forgeboot-core/README.md new file mode 100644 index 0000000..b63ed61 --- /dev/null +++ b/forgeboot-core/README.md @@ -0,0 +1,40 @@ +# forgeboot-core + +通用核心库 + +## 简介 + +`forgeboot-core` 包含项目中通用的扩展、工具与序列化支持,例如通用枚举处理、序列化接口、基础配置等。 + +## 核心功能 + +- **forgeboot-core-extension**:公共扩展函数、集合工具类等。 +- **forgeboot-core-serialization**:Jackson/Kotlin 序列化自定义注册与模块。 + +## 引入依赖 + +Maven: +```xml + + io.github.gewuyou + forgeboot-core + ${version} + +``` +使用 Gradle: +```groovy +implementation "io.github.gewuyou:forgeboot-core:${version}" +``` + +## 快速开始 + +在 Spring Boot 中引入后,自动注册序列化模块,可直接使用扩展函数。 + +## 构建 +```bash +./gradlew :forgeboot-core:build +``` + +## 许可 + +Apache-2.0 diff --git a/forgeboot-demo/README.md b/forgeboot-demo/README.md new file mode 100644 index 0000000..3272a2d --- /dev/null +++ b/forgeboot-demo/README.md @@ -0,0 +1,28 @@ +# forgeboot-demo + +示例与演示模块 + +## 简介 + +`forgeboot-demo` 包含各模块功能的示例,帮助快速了解如何在项目中使用 `forgeboot-trace`, `forgeboot-cache` 等组件。 + +## 快速开始 + +1. 进入示例模块: + ```bash + cd forgeboot-demo/forgeboot-trace-demo + ``` +2. 运行示例: + ```bash + ./gradlew bootRun + ``` +3. 访问 `http://localhost:8080/trace-demo` 查看效果。 + +## 构建 +```bash +./gradlew :forgeboot-demo:build +``` + +## 许可 + +Apache-2.0 diff --git a/forgeboot-demo/forgeboot-plugin-demo/.gitattributes b/forgeboot-demo/forgeboot-plugin-demo/.gitattributes new file mode 100644 index 0000000..8af972c --- /dev/null +++ b/forgeboot-demo/forgeboot-plugin-demo/.gitattributes @@ -0,0 +1,3 @@ +/gradlew text eol=lf +*.bat text eol=crlf +*.jar binary diff --git a/forgeboot-demo/forgeboot-plugin-demo/.gitignore b/forgeboot-demo/forgeboot-plugin-demo/.gitignore new file mode 100644 index 0000000..5a979af --- /dev/null +++ b/forgeboot-demo/forgeboot-plugin-demo/.gitignore @@ -0,0 +1,40 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Kotlin ### +.kotlin diff --git a/forgeboot-demo/forgeboot-plugin-demo/build.gradle.kts b/forgeboot-demo/forgeboot-plugin-demo/build.gradle.kts new file mode 100644 index 0000000..dc48148 --- /dev/null +++ b/forgeboot-demo/forgeboot-plugin-demo/build.gradle.kts @@ -0,0 +1,5 @@ + +dependencies { + +} + diff --git a/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-api/.gitattributes b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-api/.gitattributes new file mode 100644 index 0000000..8af972c --- /dev/null +++ b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-api/.gitattributes @@ -0,0 +1,3 @@ +/gradlew text eol=lf +*.bat text eol=crlf +*.jar binary diff --git a/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-api/.gitignore b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-api/.gitignore new file mode 100644 index 0000000..5a979af --- /dev/null +++ b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-api/.gitignore @@ -0,0 +1,40 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Kotlin ### +.kotlin diff --git a/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-api/build.gradle.kts b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-api/build.gradle.kts new file mode 100644 index 0000000..b81c21e --- /dev/null +++ b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-api/build.gradle.kts @@ -0,0 +1,7 @@ +plugins { + alias(libs.plugins.kotlin.kapt) +} +dependencies { + kapt(libs.org.pf4j) + implementation(libs.org.pf4j) +} diff --git a/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-api/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/api/GreetingProvider.kt b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-api/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/api/GreetingProvider.kt new file mode 100644 index 0000000..76b98d7 --- /dev/null +++ b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-api/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/api/GreetingProvider.kt @@ -0,0 +1,11 @@ +package com.gewuyou.forgeboot.plugin.demo.api + +/** + *问候提供者 + * + * @since 2025-07-24 15:09:07 + * @author gewuyou + */ +fun interface GreetingProvider { + fun message(): String +} \ No newline at end of file diff --git a/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-api/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/api/GreetingService.kt b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-api/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/api/GreetingService.kt new file mode 100644 index 0000000..7edf33f --- /dev/null +++ b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-api/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/api/GreetingService.kt @@ -0,0 +1,13 @@ +package com.gewuyou.forgeboot.plugin.demo.api + +import org.pf4j.ExtensionPoint + +/** + *问候服务 + * + * @since 2025-07-23 14:04:12 + * @author gewuyou + */ +fun interface GreetingService: ExtensionPoint { + fun greet(name: String): String +} \ No newline at end of file diff --git a/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/.gitattributes b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/.gitattributes new file mode 100644 index 0000000..8af972c --- /dev/null +++ b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/.gitattributes @@ -0,0 +1,3 @@ +/gradlew text eol=lf +*.bat text eol=crlf +*.jar binary diff --git a/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/.gitignore b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/.gitignore new file mode 100644 index 0000000..5a979af --- /dev/null +++ b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/.gitignore @@ -0,0 +1,40 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Kotlin ### +.kotlin diff --git a/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/build.gradle.kts b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/build.gradle.kts new file mode 100644 index 0000000..b165dff --- /dev/null +++ b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/build.gradle.kts @@ -0,0 +1,11 @@ +plugins { + alias(libs.plugins.kotlin.kapt) + alias(libs.plugins.kotlin.plugin.spring) +} +dependencies { + kapt(libs.org.pf4j) + implementation(project(Modules.Demo.Plugin.API)) + implementation(project(Modules.Plugin.CORE)) + implementation(project(Modules.Plugin.SPRING)) + implementation(libs.springBoot.starter) +} diff --git a/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/impl/PluginConfig.kt b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/impl/PluginConfig.kt new file mode 100644 index 0000000..f165ab3 --- /dev/null +++ b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/impl/PluginConfig.kt @@ -0,0 +1,21 @@ +package com.gewuyou.forgeboot.plugin.demo.impl + +import com.gewuyou.forgeboot.plugin.demo.api.GreetingProvider +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration + +/** + *插件配置 + * + * @since 2025-07-24 14:15:45 + * @author gewuyou + */ +@Configuration +class PluginConfig{ + @Bean + fun simpleGreetingService( + greetingProvider: GreetingProvider + ): SimpleGreetingService { + return SimpleGreetingService(greetingProvider) + } +} \ No newline at end of file diff --git a/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/impl/SimpleGreetingPlugin.kt b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/impl/SimpleGreetingPlugin.kt new file mode 100644 index 0000000..7ecce7b --- /dev/null +++ b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/impl/SimpleGreetingPlugin.kt @@ -0,0 +1,28 @@ +package com.gewuyou.forgeboot.plugin.demo.impl + +import com.gewuyou.forgeboot.plugin.spring.manager.SpringPluginManager +import org.pf4j.PluginWrapper +import org.pf4j.spring.SpringPlugin +import org.springframework.context.ApplicationContext +import org.springframework.context.annotation.AnnotationConfigApplicationContext + +/** + * 简单的问候插件 + * + * 插件主类,必须继承 SpringPlugin 才能在 PF4J + Spring 框架中被识别。 + * + * @author gewuyou + * @since 2025-07-24 12:12:21 + */ +class SimpleGreetingPlugin( + private val pluginWrapper: PluginWrapper, +) : SpringPlugin(pluginWrapper) { + override fun createApplicationContext(): ApplicationContext { + return AnnotationConfigApplicationContext().apply { -> + classLoader = pluginWrapper.pluginClassLoader + parent = (pluginWrapper.pluginManager as SpringPluginManager).applicationContext + register(PluginConfig::class.java) + refresh() + } + } +} \ No newline at end of file diff --git a/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/impl/SimpleGreetingService.kt b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/impl/SimpleGreetingService.kt new file mode 100644 index 0000000..05b1c38 --- /dev/null +++ b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/impl/SimpleGreetingService.kt @@ -0,0 +1,18 @@ +package com.gewuyou.forgeboot.plugin.demo.impl + +import com.gewuyou.forgeboot.plugin.demo.api.GreetingProvider +import com.gewuyou.forgeboot.plugin.demo.api.GreetingService +import org.pf4j.Extension + +/** + *简单的问候服务 + * + * @since 2025-07-24 12:08:15 + * @author gewuyou + */ +@Extension +class SimpleGreetingService ( + private val greetingProvider: GreetingProvider +): GreetingService { + override fun greet(name: String) = "${greetingProvider.message()}, $name from plugin!" +} diff --git a/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/src/main/resources/plugin.yml b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/src/main/resources/plugin.yml new file mode 100644 index 0000000..48e6b58 --- /dev/null +++ b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/src/main/resources/plugin.yml @@ -0,0 +1,4 @@ +pluginId: simple-greeting +version: 1.0.0 +pluginClass: com.gewuyou.forgeboot.plugin.demo.impl.SimpleGreetingPlugin +pluginDescription: A greeting plugin diff --git a/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/.gitattributes b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/.gitattributes new file mode 100644 index 0000000..8af972c --- /dev/null +++ b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/.gitattributes @@ -0,0 +1,3 @@ +/gradlew text eol=lf +*.bat text eol=crlf +*.jar binary diff --git a/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/.gitignore b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/.gitignore new file mode 100644 index 0000000..5a979af --- /dev/null +++ b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/.gitignore @@ -0,0 +1,40 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Kotlin ### +.kotlin diff --git a/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/build.gradle.kts b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/build.gradle.kts new file mode 100644 index 0000000..c82cb5b --- /dev/null +++ b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/build.gradle.kts @@ -0,0 +1,6 @@ +dependencies { + implementation(project(Modules.Demo.Plugin.API)) + implementation(project(Modules.Plugin.CORE)) + implementation(project(Modules.Plugin.SPRING)) + implementation(libs.springBootStarter.web) +} diff --git a/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/plugins/forgeboot-plugin-demo-impl-0.0.7-feature-6-support-plugin-modules-SNAPSHOT.jar b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/plugins/forgeboot-plugin-demo-impl-0.0.7-feature-6-support-plugin-modules-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..680394a49ae1cf416325720dd8540444b2691ecb GIT binary patch literal 5088 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 literal 0 HcmV?d00001 diff --git a/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/server/ForgebootPluginDemoServerApplication.kt b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/server/ForgebootPluginDemoServerApplication.kt new file mode 100644 index 0000000..cab66f9 --- /dev/null +++ b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/server/ForgebootPluginDemoServerApplication.kt @@ -0,0 +1,11 @@ +package com.gewuyou.forgeboot.plugin.demo.server + +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.boot.runApplication + +@SpringBootApplication +class ForgebootPluginDemoServerApplication + +fun main(args: Array) { + runApplication(*args) +} diff --git a/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/server/controller/DemoController.kt b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/server/controller/DemoController.kt new file mode 100644 index 0000000..005a8fd --- /dev/null +++ b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/server/controller/DemoController.kt @@ -0,0 +1,22 @@ +package com.gewuyou.forgeboot.plugin.demo.server.controller + +import com.gewuyou.forgeboot.plugin.demo.api.GreetingService +import org.springframework.context.annotation.Lazy +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.RequestParam +import org.springframework.web.bind.annotation.RestController + +/** + *演示控制器 + * + * @since 2025-07-24 12:37:26 + * @author gewuyou + */ +@RestController +class DemoController( + @Lazy + private val greetingService: GreetingService +) { + @GetMapping("/plugin/greet") + fun greet(@RequestParam("name") name: String) = greetingService.greet(name) +} \ No newline at end of file diff --git a/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/server/provider/ServerGreetingProvider.kt b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/server/provider/ServerGreetingProvider.kt new file mode 100644 index 0000000..46b8621 --- /dev/null +++ b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/src/main/kotlin/com/gewuyou/forgeboot/plugin/demo/server/provider/ServerGreetingProvider.kt @@ -0,0 +1,15 @@ +package com.gewuyou.forgeboot.plugin.demo.server.provider + +import com.gewuyou.forgeboot.plugin.demo.api.GreetingProvider +import org.springframework.stereotype.Component + +/** + *服务器问候提供商 + * + * @since 2025-07-24 15:10:38 + * @author gewuyou + */ +@Component +class ServerGreetingProvider: GreetingProvider { + override fun message(): String = "服务器问候" +} \ No newline at end of file diff --git a/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/src/main/resources/application.yml b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/src/main/resources/application.yml new file mode 100644 index 0000000..c352b28 --- /dev/null +++ b/forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/src/main/resources/application.yml @@ -0,0 +1,3 @@ +forgeboot: + plugin: + path: .\forgeboot-demo\forgeboot-plugin-demo\forgeboot-plugin-demo-server\plugins diff --git a/forgeboot-i18n/README.md b/forgeboot-i18n/README.md new file mode 100644 index 0000000..a555ad0 --- /dev/null +++ b/forgeboot-i18n/README.md @@ -0,0 +1,49 @@ +# forgeboot-i18n-spring-boot-starter + +国际化 (i18n) 支持模块 + +## 简介 + +`forgeboot-i18n-spring-boot-starter` 提供消息资源加载、动态刷新、注解支持等国际化能力。 + +## 核心功能 + +- **forgeboot-i18n-api**:定义消息服务接口。 +- **forgeboot-i18n-impl**:基于 Spring `MessageSource` 的默认实现,支持多语言资源。 +- **forgeboot-i18n-autoconfigure**:自动配置 `MessageSource`、配置属性读取。 + +## 引入依赖 + +Maven: +```xml + + io.github.gewuyou + forgeboot-i18n-spring-boot-starter + ${version} + +``` +使用 Gradle: +```groovy +implementation "io.github.gewuyou:forgeboot-i18n-spring-boot-starter:${version}" +``` + +## 快速开始 + +在 `application.yml` 中添加: +```yaml +forgeboot: + i18n: + basename: messages + default-locale: en_US + cache-seconds: 3600 +``` +通过 `@Autowired Messages messages; messages.get("key");` 获取消息。 + +## 构建 +```bash +./gradlew :forgeboot-i18n:build +``` + +## 许可 + +Apache-2.0 diff --git a/forgeboot-plugin/.gitattributes b/forgeboot-plugin/.gitattributes new file mode 100644 index 0000000..8af972c --- /dev/null +++ b/forgeboot-plugin/.gitattributes @@ -0,0 +1,3 @@ +/gradlew text eol=lf +*.bat text eol=crlf +*.jar binary diff --git a/forgeboot-plugin/.gitignore b/forgeboot-plugin/.gitignore new file mode 100644 index 0000000..5a979af --- /dev/null +++ b/forgeboot-plugin/.gitignore @@ -0,0 +1,40 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Kotlin ### +.kotlin diff --git a/forgeboot-plugin/build.gradle.kts b/forgeboot-plugin/build.gradle.kts new file mode 100644 index 0000000..52ab83a --- /dev/null +++ b/forgeboot-plugin/build.gradle.kts @@ -0,0 +1,4 @@ + +dependencies { + +} diff --git a/forgeboot-plugin/forgeboot-plugin-core/.gitattributes b/forgeboot-plugin/forgeboot-plugin-core/.gitattributes new file mode 100644 index 0000000..8af972c --- /dev/null +++ b/forgeboot-plugin/forgeboot-plugin-core/.gitattributes @@ -0,0 +1,3 @@ +/gradlew text eol=lf +*.bat text eol=crlf +*.jar binary diff --git a/forgeboot-plugin/forgeboot-plugin-core/.gitignore b/forgeboot-plugin/forgeboot-plugin-core/.gitignore new file mode 100644 index 0000000..5a979af --- /dev/null +++ b/forgeboot-plugin/forgeboot-plugin-core/.gitignore @@ -0,0 +1,40 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Kotlin ### +.kotlin diff --git a/forgeboot-plugin/forgeboot-plugin-core/build.gradle.kts b/forgeboot-plugin/forgeboot-plugin-core/build.gradle.kts new file mode 100644 index 0000000..32eeca2 --- /dev/null +++ b/forgeboot-plugin/forgeboot-plugin-core/build.gradle.kts @@ -0,0 +1,9 @@ + +dependencies { + api(libs.org.yaml.snakeyaml) + api(libs.org.pf4j) +} +// 全局排除 slf4j-reload4j +configurations.all { + exclude(group = "org.slf4j", module = "slf4j-reload4j") +} \ No newline at end of file diff --git a/forgeboot-plugin/forgeboot-plugin-core/src/main/kotlin/com/gewuyou/forgeboot/plugin/core/finder/MappableYamlPluginDescriptorFinder.kt b/forgeboot-plugin/forgeboot-plugin-core/src/main/kotlin/com/gewuyou/forgeboot/plugin/core/finder/MappableYamlPluginDescriptorFinder.kt new file mode 100644 index 0000000..de8974d --- /dev/null +++ b/forgeboot-plugin/forgeboot-plugin-core/src/main/kotlin/com/gewuyou/forgeboot/plugin/core/finder/MappableYamlPluginDescriptorFinder.kt @@ -0,0 +1,85 @@ +package com.gewuyou.forgeboot.plugin.core.finder + +import com.gewuyou.forgeboot.plugin.core.mapper.YamlPluginDescriptorMapper +import org.pf4j.PluginDescriptor +import org.pf4j.PluginDescriptorFinder +import org.pf4j.PluginRuntimeException +import org.pf4j.util.FileUtils +import org.yaml.snakeyaml.LoaderOptions +import org.yaml.snakeyaml.Yaml +import org.yaml.snakeyaml.constructor.Constructor +import java.io.IOException +import java.io.InputStreamReader +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.Paths + +/** + * 映射YAML插件描述符查找器 + * + * @since 2025-07-22 22:46:42 + * @author gewuyou + */ +class MappableYamlPluginDescriptorFinder( + private val metadataClass: Class, + private val descriptorMapper: YamlPluginDescriptorMapper, + private val yamlFileName: String = "plugin.yml" +) : PluginDescriptorFinder { + + /** + * 判断插件路径是否适用当前查找器 + * + * @param pluginPath 插件路径 + * @return 如果路径存在且为目录或 ZIP/JAR 文件则返回 true + */ + override fun isApplicable(pluginPath: Path): Boolean { + return Files.exists(pluginPath) && (Files.isDirectory(pluginPath) || FileUtils.isZipOrJarFile(pluginPath)) + } + + /** + * 查找并解析插件描述符 + * + * @param pluginPath 插件路径 + * @return 解析后的插件描述符 + */ + override fun find(pluginPath: Path): PluginDescriptor { + val path = getYamlPath(pluginPath) + if (!Files.exists(path)) { + throw PluginRuntimeException("Cannot find descriptor file: $path") + } + val metadata = loadYamlFromPath(path) + return descriptorMapper.mapFrom(metadata) + } + + /** + * 获取 YAML 文件的路径 + * + * @param pluginPath 插件路径 + * @return YAML 文件的路径 + */ + private fun getYamlPath(pluginPath: Path): Path { + return if (Files.isDirectory(pluginPath)) { + pluginPath.resolve(Paths.get(yamlFileName)) + } else { + try { + FileUtils.getPath(pluginPath, yamlFileName) + } catch (e: IOException) { + throw PluginRuntimeException(e) + } + } + } + + /** + * 从指定路径加载 YAML 数据 + * + * @param path YAML 文件路径 + * @return 解析后的对象 + */ + private fun loadYamlFromPath(path: Path): R { + val inputStream = Files.newInputStream(path) + val reader = InputStreamReader(inputStream, Charsets.UTF_8) + val yaml = Yaml(Constructor(metadataClass, LoaderOptions())) + return yaml.load(reader) + ?: throw PluginRuntimeException("Failed to load YAML from: $path") + } +} diff --git a/forgeboot-plugin/forgeboot-plugin-core/src/main/kotlin/com/gewuyou/forgeboot/plugin/core/finder/TypedYamlPluginDescriptorFinder.kt b/forgeboot-plugin/forgeboot-plugin-core/src/main/kotlin/com/gewuyou/forgeboot/plugin/core/finder/TypedYamlPluginDescriptorFinder.kt new file mode 100644 index 0000000..9386762 --- /dev/null +++ b/forgeboot-plugin/forgeboot-plugin-core/src/main/kotlin/com/gewuyou/forgeboot/plugin/core/finder/TypedYamlPluginDescriptorFinder.kt @@ -0,0 +1,98 @@ +package com.gewuyou.forgeboot.plugin.core.finder + +import org.pf4j.PluginDescriptor +import org.pf4j.PluginDescriptorFinder +import org.pf4j.PluginRuntimeException +import org.pf4j.util.FileUtils +import org.yaml.snakeyaml.LoaderOptions +import org.yaml.snakeyaml.Yaml +import org.yaml.snakeyaml.constructor.Constructor +import java.io.IOException +import java.io.InputStreamReader +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.Paths + +/** + * 强类型泛型YAML插件描述符查找器 + * 用于从指定路径中查找并解析YAML格式的插件描述符文件 + * + * @param descriptorClass 插件描述符的类类型,用于解析YAML文件时构造对应的对象 + * @param yamlFileName YAML文件的名称,默认为"plugin.yml" + * @since 2025-07-22 22:26:20 + * @author gewuyou + */ +open class TypedYamlPluginDescriptorFinder( + protected val descriptorClass: Class, + protected val yamlFileName: String = "plugin.yml", +) : PluginDescriptorFinder { + + /** + * 检查给定的插件路径是否适用于此查找器 + * + * @param pluginPath 插件的路径 + * @return 如果路径存在且为目录或ZIP/JAR文件,则返回true,否则返回false + */ + override fun isApplicable(pluginPath: Path): Boolean { + return Files.exists(pluginPath) && (Files.isDirectory(pluginPath) || FileUtils.isZipOrJarFile(pluginPath)) + } + + /** + * 在给定的插件路径中查找并解析插件描述符 + * + * @param pluginPath 插件的路径 + * @return 解析后的PluginDescriptor对象 + * @throws PluginRuntimeException 如果无法找到描述符文件,则抛出此异常 + */ + override fun find(pluginPath: Path): PluginDescriptor { + val path = getYamlPath(pluginPath) + if (!Files.exists(path)) { + throw PluginRuntimeException("Cannot find descriptor file: $path") + } + return parseYamlDescriptor(path) + } + + /** + * 获取YAML描述符文件的路径 + * + * @param pluginPath 插件的路径 + * @return 描述符文件的路径 + * @throws PluginRuntimeException 如果路径不存在,则抛出此异常 + */ + private fun getYamlPath(pluginPath: Path): Path { + if (Files.isDirectory(pluginPath)) { + return pluginPath.resolve(Paths.get(yamlFileName)) + } + // 处理ZIP或JAR文件的情况,获取其中的YAML文件路径 + try { + return FileUtils.getPath(pluginPath, yamlFileName) + } catch (e: IOException) { + throw PluginRuntimeException(e) + } + } + + /** + * 解析YAML格式的插件描述符 + * + * @param path 插件描述符的路径 + * @return 解析后的PluginDescriptor对象 + */ + protected open fun parseYamlDescriptor(path: Path): PluginDescriptor { + return loadYamlFromPath(path) + } + + /** + * 从指定路径加载YAML文件并解析为指定的类型 + * + * @param path YAML文件的路径 + * @return 解析后的对象,类型为T + * @throws PluginRuntimeException 如果加载或解析YAML失败,则抛出此异常 + */ + protected fun loadYamlFromPath(path: Path): T { + val inputStream = Files.newInputStream(path) + val reader = InputStreamReader(inputStream, Charsets.UTF_8) + val yaml = Yaml(Constructor(descriptorClass, LoaderOptions())) + return yaml.load(reader) + ?: throw PluginRuntimeException("Failed to load YAML from: $path") + } +} diff --git a/forgeboot-plugin/forgeboot-plugin-core/src/main/kotlin/com/gewuyou/forgeboot/plugin/core/finder/YamlPluginDescriptorFinder.kt b/forgeboot-plugin/forgeboot-plugin-core/src/main/kotlin/com/gewuyou/forgeboot/plugin/core/finder/YamlPluginDescriptorFinder.kt new file mode 100644 index 0000000..e854ffe --- /dev/null +++ b/forgeboot-plugin/forgeboot-plugin-core/src/main/kotlin/com/gewuyou/forgeboot/plugin/core/finder/YamlPluginDescriptorFinder.kt @@ -0,0 +1,77 @@ +package com.gewuyou.forgeboot.plugin.core.finder + +import org.pf4j.* +import org.pf4j.util.FileUtils +import org.yaml.snakeyaml.LoaderOptions +import org.yaml.snakeyaml.Yaml +import java.io.InputStreamReader +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.Paths + + +/** + *YAML插件描述符查找器 + * + * @since 2025-07-24 13:24:18 + * @author gewuyou + */ +class YamlPluginDescriptorFinder( + private val yamlFileName: String = "plugin.yml", +) : PluginDescriptorFinder { + + class YamlDescriptor { + var pluginId: String? = null + var pluginDescription: String? = null + var pluginClass: String? = null + var version: String? = null + var provider: String? = null + var dependencies: String? = null + var requires: String = "*" // SemVer format + var license: String? = null + } + + + override fun isApplicable(pluginPath: Path): Boolean { + return Files.exists(pluginPath) && (Files.isDirectory(pluginPath) || FileUtils.isZipOrJarFile(pluginPath)) + } + + override fun find(pluginPath: Path): PluginDescriptor { + val descriptorPath = getYamlPath(pluginPath) + if (!Files.exists(descriptorPath)) { + throw PluginRuntimeException("YAML descriptor file not found: $descriptorPath") + } + + val yaml = Yaml(LoaderOptions()) + val reader = InputStreamReader(Files.newInputStream(descriptorPath), Charsets.UTF_8) + val yamlDescriptor = yaml.loadAs(reader, YamlDescriptor::class.java) + + return DefaultPluginDescriptor( + yamlDescriptor.pluginId, + yamlDescriptor.pluginDescription, + yamlDescriptor.pluginClass, + yamlDescriptor.version, + yamlDescriptor.requires, + yamlDescriptor.provider, + yamlDescriptor.license + ).apply { + yamlDescriptor.dependencies + ?.split(",") + ?.map { it.trim() } + ?.filter { it.isNotEmpty() } + ?.forEach { addDependency(PluginDependency(it)) } + } + } + + private fun getYamlPath(pluginPath: Path): Path { + return if (Files.isDirectory(pluginPath)) { + pluginPath.resolve(Paths.get(yamlFileName)) + } else { + try { + FileUtils.getPath(pluginPath, yamlFileName) + } catch (e: Exception) { + throw PluginRuntimeException(e) + } + } + } +} diff --git a/forgeboot-plugin/forgeboot-plugin-core/src/main/kotlin/com/gewuyou/forgeboot/plugin/core/mapper/YamlPluginDescriptorMapper.kt b/forgeboot-plugin/forgeboot-plugin-core/src/main/kotlin/com/gewuyou/forgeboot/plugin/core/mapper/YamlPluginDescriptorMapper.kt new file mode 100644 index 0000000..704d39e --- /dev/null +++ b/forgeboot-plugin/forgeboot-plugin-core/src/main/kotlin/com/gewuyou/forgeboot/plugin/core/mapper/YamlPluginDescriptorMapper.kt @@ -0,0 +1,25 @@ +package com.gewuyou.forgeboot.plugin.core.mapper + +import org.pf4j.PluginDescriptor + +/** + * YAML插件描述符映射器 + * + * 该函数式接口用于将一种数据结构(R类型)映射为插件描述符对象(T类型,继承自PluginDescriptor)。 + * 主要用于插件系统中对不同格式的描述信息进行统一转换。 + * + * @param T 插件描述符类型,必须继承自 PluginDescriptor + * @param R 源数据类型,用于提供映射所需的原始信息 + * + * @since 2025-07-22 22:45:25 + * @author gewuyou + */ +fun interface YamlPluginDescriptorMapper { + /** + * 将给定的源数据对象映射为插件描述符实例。 + * + * @param metadata 提供映射所需数据的源对象 + * @return 返回映射生成的插件描述符对象(T类型) + */ + fun mapFrom(metadata: R): T +} \ No newline at end of file diff --git a/forgeboot-plugin/forgeboot-plugin-spring/.gitattributes b/forgeboot-plugin/forgeboot-plugin-spring/.gitattributes new file mode 100644 index 0000000..8af972c --- /dev/null +++ b/forgeboot-plugin/forgeboot-plugin-spring/.gitattributes @@ -0,0 +1,3 @@ +/gradlew text eol=lf +*.bat text eol=crlf +*.jar binary diff --git a/forgeboot-plugin/forgeboot-plugin-spring/.gitignore b/forgeboot-plugin/forgeboot-plugin-spring/.gitignore new file mode 100644 index 0000000..c2065bc --- /dev/null +++ b/forgeboot-plugin/forgeboot-plugin-spring/.gitignore @@ -0,0 +1,37 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ diff --git a/forgeboot-plugin/forgeboot-plugin-spring/build.gradle.kts b/forgeboot-plugin/forgeboot-plugin-spring/build.gradle.kts new file mode 100644 index 0000000..2f8675b --- /dev/null +++ b/forgeboot-plugin/forgeboot-plugin-spring/build.gradle.kts @@ -0,0 +1,11 @@ +dependencies { + api(libs.org.yaml.snakeyaml) + api(libs.org.pf4jSpring) + compileOnly(libs.springBoot.starter) + implementation(project(Modules.Plugin.CORE)) + implementation(project(Modules.Core.EXTENSION)) +} +// 全局排除 slf4j-reload4j +configurations.all { + exclude(group = "org.slf4j", module = "slf4j-reload4j") +} \ No newline at end of file diff --git a/forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/IsolatedSpringPlugin.kt b/forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/IsolatedSpringPlugin.kt new file mode 100644 index 0000000..120802f --- /dev/null +++ b/forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/IsolatedSpringPlugin.kt @@ -0,0 +1,48 @@ +package com.gewuyou.forgeboot.plugin.spring + +import org.pf4j.PluginWrapper +import org.pf4j.spring.SpringPlugin +import org.springframework.context.ApplicationContext +import org.springframework.context.annotation.AnnotationConfigApplicationContext + +/** + * 隔离的Spring插件 + * + * 该抽象类继承自SpringPlugin,提供了独立的Spring应用上下文, + * 使得每个插件可以在自己的上下文中管理Bean,实现插件间的隔离。 + * + * @property pluginWrapper 插件包装器,提供插件的基本信息和类加载器 + * + * @since 2025-07-24 15:26:45 + * @author gewuyou + */ +abstract class IsolatedSpringPlugin( + private val pluginWrapper: PluginWrapper +) : SpringPlugin(pluginWrapper) { + + /** + * 创建应用上下文 + * + * 该方法覆盖了父类的实现,创建一个独立的AnnotationConfigApplicationContext, + * 设置插件的类加载器,并注册插件特定的配置类。 + * + * @return 配置完成的ApplicationContext实例 + */ + override fun createApplicationContext(): ApplicationContext { + return AnnotationConfigApplicationContext().apply { + classLoader = pluginWrapper.pluginClassLoader + register(pluginConfigurationClass()) + refresh() + } + } + + /** + * 获取插件配置类 + * + * 抽象方法,子类需要提供插件特定的配置类, + * 该配置类将被注册到插件的应用上下文中。 + * + * @return 插件配置类的Class对象 + */ + abstract fun pluginConfigurationClass(): Class<*> +} \ No newline at end of file diff --git a/forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/MergedSpringPlugin.kt b/forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/MergedSpringPlugin.kt new file mode 100644 index 0000000..7c6f120 --- /dev/null +++ b/forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/MergedSpringPlugin.kt @@ -0,0 +1,54 @@ +package com.gewuyou.forgeboot.plugin.spring + +import org.pf4j.PluginWrapper +import org.pf4j.spring.SpringPlugin +import org.pf4j.spring.SpringPluginManager +import org.springframework.context.ApplicationContext +import org.springframework.context.annotation.AnnotationConfigApplicationContext +import org.springframework.core.env.ConfigurableEnvironment + +/** + * 合并的Spring插件 + * + * 该抽象类继承自SpringPlugin,与IsolatedSpringPlugin不同, + * 它创建的插件应用上下文与主应用上下文建立父子关系, + * 使得插件可以访问主应用上下文中的Bean,实现插件与主应用的合并。 + * + * @property pluginWrapper 插件包装器,提供插件的基本信息和类加载器 + * + * @since 2025-07-24 15:35:52 + * @author gewuyou + */ +abstract class MergedSpringPlugin( + private val pluginWrapper: PluginWrapper +) : SpringPlugin(pluginWrapper) { + + /** + * 创建应用上下文 + * + * 该方法覆盖了父类的实现,创建一个与主应用上下文有关联的AnnotationConfigApplicationContext, + * 设置插件的类加载器,建立父子上下文关系,并注册插件特定的配置类。 + * + * @return 配置完成的ApplicationContext实例 + */ + override fun createApplicationContext(): ApplicationContext { + return AnnotationConfigApplicationContext().apply { + classLoader = pluginWrapper.pluginClassLoader + parent = (pluginWrapper.pluginManager as SpringPluginManager).applicationContext + // 保证配置文件能读取 + environment = parent?.environment as ConfigurableEnvironment + register(pluginConfigurationClass()) + refresh() + } + } + + /** + * 获取插件配置类 + * + * 抽象方法,子类需要提供插件特定的配置类, + * 该配置类将被注册到插件的应用上下文中。 + * + * @return 插件配置类的Class对象 + */ + abstract fun pluginConfigurationClass(): Class<*> +} \ No newline at end of file diff --git a/forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/config/PluginSpringAutoConfiguration.kt b/forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/config/PluginSpringAutoConfiguration.kt new file mode 100644 index 0000000..2a55b0f --- /dev/null +++ b/forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/config/PluginSpringAutoConfiguration.kt @@ -0,0 +1,52 @@ +package com.gewuyou.forgeboot.plugin.spring.config + +import com.gewuyou.forgeboot.plugin.spring.manager.SpringPluginManager +import org.pf4j.DefaultPluginManager.PLUGINS_DIR_CONFIG_PROPERTY_NAME +import org.pf4j.ExtensionFactory +import org.pf4j.PluginManager +import org.pf4j.spring.SingletonSpringExtensionFactory +import org.springframework.beans.factory.annotation.Value +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import java.nio.file.Paths + +/** + * 插件Spring自动配置类 + * + * 该类用于在Spring环境中自动配置插件管理器及相关功能。 + * 提供了插件管理器的Bean定义以及插件集成的初始化逻辑。 + * + * @since 2025-07-23 13:01:27 + * @author gewuyou + */ +@Configuration +class PluginSpringAutoConfiguration() { + /** + * 提供一个默认的插件管理器Bean。 + * + * 当Spring容器中尚未定义PluginManager类型的Bean时, + * 该方法将创建并配置一个SpringPluginManager实例作为默认插件管理器。 + * 插件路径通过@Value注解从配置文件中解析,若未配置则使用默认值。 + * + * @param pluginPath 插件存放路径,从配置文件中读取,默认值为"plugins" + * @return 返回一个配置好的PluginManager实例,用于管理插件的生命周期和功能 + */ + @Bean + @ConditionalOnMissingBean + fun pluginManager(@Value("\${forgeboot.plugin.path}") pluginPath: String = PLUGINS_DIR_CONFIG_PROPERTY_NAME): PluginManager { + return SpringPluginManager(listOf(Paths.get(pluginPath))) + } + /** + * 创建并配置ExtensionFactory实例 + * 该方法在插件管理器初始化之后调用,用于创建扩展工厂,进一步扩展系统功能 + * + * @param pluginManager 已初始化并启动的插件管理器,用于扩展工厂的构建 + * @return ExtensionFactory 初始化后的扩展工厂实例 + */ + @Bean + @ConditionalOnMissingBean + fun extensionFactory(pluginManager: PluginManager): ExtensionFactory { + return SingletonSpringExtensionFactory(pluginManager) + } +} \ No newline at end of file diff --git a/forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/manager/SpringPluginManager.kt b/forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/manager/SpringPluginManager.kt new file mode 100644 index 0000000..8a708da --- /dev/null +++ b/forgeboot-plugin/forgeboot-plugin-spring/src/main/kotlin/com/gewuyou/forgeboot/plugin/spring/manager/SpringPluginManager.kt @@ -0,0 +1,25 @@ +package com.gewuyou.forgeboot.plugin.spring.manager + +import com.gewuyou.forgeboot.plugin.core.finder.YamlPluginDescriptorFinder +import org.pf4j.CompoundPluginDescriptorFinder +import org.pf4j.ManifestPluginDescriptorFinder +import org.pf4j.PropertiesPluginDescriptorFinder +import org.pf4j.spring.SpringPluginManager +import java.nio.file.Path + +/** + *Spring插件管理器 + * + * @since 2025-07-24 13:15:40 + * @author gewuyou + */ +open class SpringPluginManager( + pluginsRoots: List, +) : SpringPluginManager(pluginsRoots) { + override fun createPluginDescriptorFinder(): CompoundPluginDescriptorFinder { + return CompoundPluginDescriptorFinder() + .add(YamlPluginDescriptorFinder()) + .add(PropertiesPluginDescriptorFinder()) + .add(ManifestPluginDescriptorFinder()) + } +} \ No newline at end of file diff --git a/forgeboot-plugin/forgeboot-plugin-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/forgeboot-plugin/forgeboot-plugin-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..f136950 --- /dev/null +++ b/forgeboot-plugin/forgeboot-plugin-spring/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +com.gewuyou.forgeboot.plugin.spring.config.PluginSpringAutoConfiguration diff --git a/forgeboot-trace/README.md b/forgeboot-trace/README.md new file mode 100644 index 0000000..436c8bc --- /dev/null +++ b/forgeboot-trace/README.md @@ -0,0 +1,84 @@ +# forgeboot-trace-spring-boot-starter + +> 🔍 分布式调用链追踪模块,基于上下文感知系统实现 requestId / traceId 的自动生成、注入与传播,适配协程、Reactor、线程池等多种执行模型。 + +--- + +## 🧩 简介 + +`forgeboot-trace-spring-boot-starter` 是 ForgeBoot 提供的轻量级调用链追踪模块,致力于在服务内部及分布式场景中提供统一的 traceId 管理机制。 + +该模块依赖 `forgeboot-context` 实现 traceId 的透明传递,支持与日志系统(MDC)、Web 框架(Servlet / WebFlux)无缝集成。 + +--- + +## ✨ 核心功能 + +- ✅ 支持全局唯一的 traceId/requestId 自动生成与注入 +- ✅ 与日志系统集成(MDC 支持) +- ✅ 支持从 HTTP 请求头中自动提取 traceId +- ✅ 基于 `forgeboot-context` 实现跨线程 / 协程 / Reactor 任务 traceId 传递 +- ✅ 可配置的 traceId 生成策略(内置 UUID,支持扩展如 OpenTelemetry) +- ✅ 适配 Spring Boot 自动装配,开箱即用 + +--- + +## 📦 引入依赖 + +使用 Maven: + +```xml + + io.github.gewuyou + forgeboot-trace-spring-boot-starter + ${version} + +``` + +使用 Gradle: + +```groovy +implementation "io.github.gewuyou:forgeboot-trace-spring-boot-starter:${version}" +``` + +--- + +## 🚀 快速开始 + +1. 引入依赖并启用自动配置(Spring Boot 自动生效) + +2. 在日志配置中添加 traceId(以 logback 为例): + + ```xml + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level traceId=%X{traceId} %logger{36} - %msg%n + ``` + +3. 可在任何业务代码中通过上下文访问: + +```kotlin +val traceId = ContextHolder.get("traceId") +``` + +--- + +## ⚙️ 构建方式 + +使用 Gradle 命令进行构建发布: + +```bash +./gradlew :forgeboot-trace:build +``` + +--- + +## 📄 许可 + +本项目采用 [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) 开源协议。 + +--- + +## 📬 联系作者 + +由 [@gewuyou](https://github.com/gewuyou) 维护。 + +欢迎提交 Issue 或 PR 改进本模块! diff --git a/forgeboot-webmvc/README.md b/forgeboot-webmvc/README.md new file mode 100644 index 0000000..0b0c60a --- /dev/null +++ b/forgeboot-webmvc/README.md @@ -0,0 +1,47 @@ +# forgeboot-webmvc-spring-boot-starter + +Web MVC 通用组件集合 + +## 简介 + +`forgeboot-webmvc-spring-boot-starter` 提供常用 Web 层组件,如版本管理、统一日志、全局异常处理、DTO 封装、参数校验、接口规范等。 + +## 核心模块 + +- **forgeboot-webmvc-version-spring-boot-starter**:API 版本控制 +- **forgeboot-webmvc-logger-spring-boot-starter**:请求/响应日志 AOP +- **forgeboot-webmvc-exception-spring-boot-starter**:全局异常处理 +- **forgeboot-webmvc-exception-i18n-spring-boot-starter**:异常国际化 +- **forgeboot-webmvc-dto**:统一返回结构与分页工具 +- **forgeboot-webmvc-validation**:请求校验封装 +- **forgeboot-webmvc-spec**:自动生成接口规范文档 + +## 引入依赖 + +Maven: +```xml + + io.github.gewuyou + forgeboot-webmvc-spring-boot-starter + ${version} + +``` +使用 Gradle: +```groovy +implementation "io.github.gewuyou:forgeboot-webmvc-spring-boot-starter:${version}" +``` + +## 快速开始 + +- 在 `application.yml` 中配置各模块开关和策略。 +- 使用 `BaseResult` 或 `PageResult` 封装返回值。 +- Controller 中使用 `@ApiVersion`, `@Validated` 等注解。 + +## 构建 +```bash +./gradlew :forgeboot-webmvc:build +``` + +## 许可 + +Apache-2.0 diff --git a/forgeboot-webmvc/dto/README.md b/forgeboot-webmvc/dto/README.md new file mode 100644 index 0000000..2694826 --- /dev/null +++ b/forgeboot-webmvc/dto/README.md @@ -0,0 +1,197 @@ +# forgeboot-webmvc-dto + +> 📦 Web 项目通用 DTO 模块,包含统一响应封装、分页/排序/过滤模型、JPA 查询构造扩展等内容。 + +--- + +## 🧩 简介 + +`forgeboot-webmvc-dto` 是 ForgeBoot 提供的 Web 项目 DTO 抽象模块,封装了常用的分页、排序、状态过滤等通用接口与请求模型,并提供统一的响应结构与查询构建工具,助力快速开发一致性良好的接口风格。 + +--- + +## ✨ 核心功能 + +- ✅ 标准化 API 响应结构:`BaseResult` / `PageResult` / `R` +- ✅ 通用分页/排序/过滤参数模型:`Pageable`, `Sortable`, `StatusFilterable` +- ✅ 查询构件组合接口:`QueryComponent` + 多种 Filterable 接口 +- ✅ JPA 查询扩展支持:`JpaPredicateExtensions`, `PredicateExtensions` +- ✅ 响应信息国际化扩展:`I18nResult` +- ✅ 日期范围、关键字等实体查询条件模型 + +--- + +## 📦 引入依赖 + +使用 Maven: + +```xml + + io.github.gewuyou + forgeboot-webmvc-dto + ${version} + +``` + +使用 Gradle: + +```groovy +implementation "io.github.gewuyou:forgeboot-webmvc-dto:${version}" +``` + +--- + +## 🚀 快速开始 + +### ✅ 统一响应使用示例 + +```kotlin +@GetMapping("/hello") +fun hello(): R { + return R.ok("Hello, world!") +} +``` + +### ✅ 构建分页查询请求 + +```kotlin +data class UserPageRequest( + override val currentPage: Int, + override val pageSize: Int, + override val keyword: String? +) : Pageable, KeywordSearchable +``` + +结合 JPA Predicate 扩展: + +```kotlin +fun buildPredicate(request: UserPageRequest): Predicate { + return where { + orLike("username", request.keyword) + andEqual("status", "ACTIVE") + } +} +``` + +--- + +## 📘 高级用法 + +### 🔄 自动封装分页响应 + +```kotlin +fun toPageResult(page: Page): PageResult { + return PageResult.of(page) +} +``` + +控制器示例: + +```kotlin +@GetMapping("/users") +fun listUsers(request: UserPageRequest): PageResult { + val page = userService.query(request) + return PageResult.of(page) +} +``` + +### 🔍 自定义查询组件组合 + +你可以组合多种查询接口,让请求类直接实现 `QueryComponent`,构建强类型的 DSL 查询请求对象: + +```kotlin +data class ProductQueryRequest( + override val currentPage: Int, + override val pageSize: Int, + override val keyword: String?, + override val status: Int?, + override val dateRange: DateRangeCondition? +) : QueryComponent, Pageable, KeywordSearchable, StatusFilterable, DateRangeFilterable +``` + +一旦实现了这些接口,你就可以直接在 Controller 中使用 `.toJpaQuery()` 方法,无需再手动构建查询逻辑: + +```kotlin +@GetMapping("/products") +fun query(request: ProductQueryRequest): PageResult { + val (spec, pageRequest) = request.toJpaQuery() + val page = productRepository.findAll(spec, pageRequest) + return PageResult.of(page.map { it.toDTO() }) +} +``` + +> ✅ 会自动根据你实现的接口生成分页、排序、关键字搜索、状态过滤、日期范围等查询条件,无需重复写繁琐的 JPA 条件拼接逻辑。 + + +--- + +## 🔍 JPA 查询构造器扩展 + +你可以使用 `QueryComponent.toJpaQuery()` 一键将请求对象转换为 JPA 查询规范和分页条件。 + +### ✅ 示例请求类 + +```kotlin +data class ProductQueryRequest( + override val currentPage: Int, + override val pageSize: Int, + override val keyword: String?, + override val status: Int?, + override val dateRange: DateRangeCondition? +) : Pageable, Sortable, KeywordSearchable, StatusFilterable, DateRangeFilterable +``` + +### ✅ 控制器代码(极简) + +```kotlin +@GetMapping("/products") +fun query(request: ProductQueryRequest): PageResult { + val (spec, pageRequest) = request.toJpaQuery() + val page = productRepository.findAll(spec, pageRequest) + return PageResult.of(page.map { it.toDTO() }) +} +``` + +### ✅ 内部处理逻辑(你无需手写) + +- 组合关键字模糊查询:`like lower(name)`、`like lower(description)` +- 处理状态过滤:`where status = ?` +- 构建日期范围:`createdAt >= ? and createdAt <= ?` +- 构建排序条件(多字段或默认排序) +- 构建分页信息(从 `currentPage` 开始,默认每页 10 条) + +> 默认行为:如果请求未实现 `Pageable` 或 `Sortable`,会使用默认分页第 1 页、每页 10 条,无排序。 + +--- + +## 🧩 扩展组件介绍 + + + +| 模块 | 说明 | +|--------------------------|----------------------------| +| `BaseResult` | 基础响应模型(带状态码与信息) | +| `PageResult` | 分页响应结构 | +| `R` | 快捷响应构造器(等价于 Result.ok/err) | +| `Pageable` | 分页能力接口 | +| `Sortable` | 排序参数接口 | +| `Filterable` | 通用过滤接口(可自定义字段过滤) | +| `QueryComponent` | 查询字段组合容器(支持 DSL 构造) | +| `DateRangeCondition` | 日期范围过滤器 | +| `JpaPredicateExtensions` | JPA 查询构建扩展函数集 | + + + +--- + +## 📄 许可协议 + +本项目采用 [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) 开源协议。 + +--- + +## 📬 联系作者 + +由 [@gewuyou](https://github.com/gewuyou) 维护。 + +欢迎提交 Issue 或 PR 改进本模块! diff --git a/forgeboot-webmvc/dto/build.gradle.kts b/forgeboot-webmvc/dto/build.gradle.kts index 991bf82..90b691c 100644 --- a/forgeboot-webmvc/dto/build.gradle.kts +++ b/forgeboot-webmvc/dto/build.gradle.kts @@ -9,7 +9,6 @@ dependencies { compileOnly(libs.jackson.annotations) compileOnly(libs.springBootStarter.jpa) compileOnly(libs.springBootStarter.validation) - compileOnly(libs.org.mapstruct) } i18nKeyGen { rootPackage.set("com.gewuyou.forgeboot.webmvc.dto.i18n") diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/mapper/BaseMapper.kt b/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/mapper/BaseMapper.kt deleted file mode 100644 index 34d2466..0000000 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/mapper/BaseMapper.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.gewuyou.forgeboot.webmvc.dto.mapper - -import org.mapstruct.BeanMapping -import org.mapstruct.MappingTarget -import org.mapstruct.NullValuePropertyMappingStrategy - -/** - * Base Mapper(基础映射器) - * 提供基础的对象映射操作定义,包含合并、覆盖合并、单个对象拷贝及列表拷贝的方法。 - * - * @since 2025-05-30 22:50:18 - * @author gewuyou - */ -interface BaseMapper { - /** - * 将 source 对象中的非 null 属性合并到 target 对象中。 - * 注意:null 值的属性不会覆盖 target 中已有的值。 - * - * @param target 目标对象,将被更新 - * @param source 源对象,提供需要合并的数据 - */ - @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) - fun mergeIgnoreNull(@MappingTarget target: T, source: S) - - /** - * 全量覆盖合并 source 到 target。 - * 注意:即使 source 中的字段为 null,也会覆盖 target 中对应的字段。 - * - * @param target 目标对象,将被更新 - * @param source 源对象,提供需要合并的数据 - */ - fun overwriteMerge(@MappingTarget target: T, source: S) - - /** - * 将 source 对象的内容拷贝到一个新的 T 类型对象中。 - * - * @param source 源对象,提供数据 - * @return 返回一个新的目标类型对象 - */ - fun copy(source: S): T - - /** - * 将源对象列表中的每个元素拷贝为新的目标类型对象,生成一个目标对象列表。 - * - * @param sources 源对象列表 - * @return 返回目标类型对象的列表 - */ - fun copyList(sources: List): List -} \ No newline at end of file diff --git a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/mapper/ConversionMapper.kt b/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/mapper/ConversionMapper.kt deleted file mode 100644 index 014cd47..0000000 --- a/forgeboot-webmvc/dto/src/main/kotlin/com/gewuyou/forgeboot/webmvc/dto/mapper/ConversionMapper.kt +++ /dev/null @@ -1,63 +0,0 @@ -package com.gewuyou.forgeboot.webmvc.dto.mapper - -import org.mapstruct.BeanMapping -import org.mapstruct.MappingTarget -import org.mapstruct.NullValuePropertyMappingStrategy - -/** - * 转换映射器接口 - * - * 提供通用的实体类(Entity)与数据传输对象(DTO)之间的双向转换能力。 - * 该接口定义了基础的数据转换方法,包括单个对象和集合对象的转换, - * 并支持部分更新操作(忽略空值属性)。 - * - * @param 实体类类型 - * @param 数据传输对象类型 - * - * @since 2025-05-30 22:53:35 - * @author gewuyou - */ -interface ConversionMapper { - /** - * 将实体对象转换为对应的DTO对象 - * - * @param entity 需要转换的实体对象 - * @return 转换后的DTO对象 - */ - fun toDto(entity: Entity): Dto - - /** - * 将DTO对象转换为对应的实体对象 - * - * @param dto 需要转换的DTO对象 - * @return 转换后的实体对象 - */ - fun toEntity(dto: Dto): Entity - - /** - * 将实体对象列表转换为对应的DTO对象列表 - * - * @param entityList 需要转换的实体对象列表 - * @return 转换后的DTO对象列表 - */ - fun toDtoList(entityList: List): List - - /** - * 将DTO对象列表转换为对应的实体对象列表 - * - * @param dtoList 需要转换的DTO对象列表 - * @return 转换后的实体对象列表 - */ - fun toEntityList(dtoList: List): List - - /** - * 使用非空属性对实体进行部分更新 - * - * 注意:此操作不会覆盖实体中为空的属性 - * - * @param dto 需要用于更新的DTO对象 - * @param entity 需要被更新的实体对象 - */ - @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) - fun partialUpdate(dto: Dto, @MappingTarget entity: Entity) -} diff --git a/forgeboot-webmvc/spec/README.md b/forgeboot-webmvc/spec/README.md new file mode 100644 index 0000000..51483b1 --- /dev/null +++ b/forgeboot-webmvc/spec/README.md @@ -0,0 +1,117 @@ +# forgeboot-webmvc-spec + +> 🧩 Web 项目通用 CRUD 接口规范模块,封装 Repository 与 Service 层的标准增删改查接口与默认实现,简化重复代码。 + +--- + +## 🧩 简介 + +`forgeboot-webmvc-spec` 是 ForgeBoot 提供的统一接口规范模块,旨在为常见的 Web 开发提供可复用的 Repository 和 Service 层增删改查基础接口及实现模板。 + +通过继承和组合该模块中的接口和基类,可以快速构建具有一致风格的业务组件,提升开发效率、降低重复代码、统一项目结构。 + +--- + +## ✨ 核心功能 + +- ✅ `CrudRepositorySpec`:通用 Repository 接口规范(继承自 `JpaRepository`) +- ✅ `CrudServiceSpec`:业务层接口标准化定义 +- ✅ `CrudServiceImplSpec`:默认 Service 实现(依赖 Repository) +- ✅ 泛型支持 Entity 类型与主键类型的自动推导 +- ✅ 与 DTO 模块 (`forgeboot-webmvc-dto`) 无缝协作 + +--- + +## 📦 引入依赖 + +使用 Maven: + +```xml + + io.github.gewuyou + forgeboot-webmvc-spec + ${version} + +``` + +使用 Gradle: + +```groovy +implementation "io.github.gewuyou:forgeboot-webmvc-spec:${version}" +``` + +--- + +## 🚀 快速开始 + +### ✅ 定义实体类 + +```kotlin +@Entity +data class Product( + @Id val id: Long, + val name: String, + val status: Int +) +``` + +### ✅ 创建 Repository 接口 + +```kotlin +interface ProductRepository : CrudRepositorySpec +``` + +### ✅ 创建 Service 接口 + +```kotlin +interface ProductService : CrudServiceSpec +``` + +### ✅ 创建默认实现类 + +```kotlin +@Service +class ProductServiceImpl( + override val repository: ProductRepository +) : CrudServiceImplSpec(), ProductService +``` + +现在你就拥有了以下功能: +- 新增:`save(entity)` +- 修改:`updateById(id, modifier)` +- 删除:`deleteById(id)` +- 查询单个:`findById(id)` +- 查询全部:`findAll()` + +--- + +## 🧩 扩展方法(默认实现中提供) + +```kotlin +fun updateById(id: ID, modifier: (T) -> Unit): Boolean +fun existsById(id: ID): Boolean +fun deleteById(id: ID): Boolean +``` + +可自由覆写或组合使用。 + +--- + +## 🧠 与其他模块集成建议 + +| 模块 | 集成方式说明 | +|------------------------|-------------------------------------------| +| `forgeboot-webmvc-dto` | 可配合 `PageResult`, `QueryComponent` 返回分页数据 | +--- + +## 📄 许可协议 + +本项目采用 [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) 开源协议。 + +--- + +## 📬 联系作者 + +由 [@gewuyou](https://github.com/gewuyou) 维护。 + +欢迎提交 Issue 或 PR 改进本模块! diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b8afd5e..7860758 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -17,6 +17,10 @@ slf4j-version = "2.0.17" map-struct-version="1.6.3" caffeine-version="3.2.1" redisson-version="3.50.0" +org-pf4j-version = "3.13.0" +org-pf4j-spring-version = "0.10.0" +org-yaml-snakeyaml-version = "2.4" +org-yaml-snakeyaml-engine-version = "2.9" [libraries] kotlinGradlePlugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin-version" } kotlinxDatetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinxDatetime-version" } @@ -41,7 +45,7 @@ springBootStarter-redis = { group = "org.springframework.boot", name = "spring-b redisson-springBootStarter= { group = "org.redisson", name = "redisson-spring-boot-starter", version.ref = "redisson-version" } springBoot-configuration-processor = { group = "org.springframework.boot", name = "spring-boot-configuration-processor", version.ref = "spring-boot-version" } springBoot-autoconfigure = { group = "org.springframework.boot", name = "spring-boot-autoconfigure" } - +springBoot-starter = { group = "org.springframework.boot", name = "spring-boot-starter" } springExpression = { group = "org.springframework", name = "spring-expression", version.ref = "spring-framework-version" } springCloudDependencies-bom = { module = "org.springframework.cloud:spring-cloud-dependencies", version.ref = "spring-cloud-version" } @@ -57,6 +61,10 @@ jackson-module-kotlin = { group = "com.fasterxml.jackson.module", name = "jackso reactor-core = { group = "io.projectreactor", name = "reactor-core" } #org org-mapstruct = { group = "org.mapstruct", name = "mapstruct", version.ref = "map-struct-version" } +org-snakeyaml-snakeyamlEngine = { group = "org.snakeyaml", name = "snakeyaml-engine", version.ref = "org-yaml-snakeyaml-engine-version" } +org-yaml-snakeyaml = { group = "org.yaml", name = "snakeyaml", version.ref = "org-yaml-snakeyaml-version" } +org-pf4j = { group = "org.pf4j", name = "pf4j", version.ref = "org-pf4j-version" } +org-pf4jSpring = { group = "org.pf4j", name = "pf4j-spring", version.ref = "org-pf4j-spring-version" } # Libraries can be bundled together for easier import # jwt jjwt-api = { module = "io.jsonwebtoken:jjwt-api", version.ref = "jjwt-version" } @@ -64,6 +72,8 @@ jjwt-impl = { module = "io.jsonwebtoken:jjwt-impl", version.ref = "jjwt-version" jjwt-jackson = { module = "io.jsonwebtoken:jjwt-jackson", version.ref = "jjwt-version" } # com com-github-benManes-caffeine = { module = "com.github.ben-manes.caffeine:caffeine",version.ref = "caffeine-version" } +# io + [bundles] kotlinxEcosystem = ["kotlinxDatetime", "kotlinxSerialization", "kotlinxCoroutines-core"] jacksonAll = [ diff --git a/settings.gradle.kts b/settings.gradle.kts index 51e3d31..81c7cd5 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -136,50 +136,25 @@ project(":forgeboot-trace:forgeboot-trace-impl").name = "forgeboot-trace-impl" project(":forgeboot-trace:forgeboot-trace-autoconfigure").name = "forgeboot-trace-autoconfigure" //endregion -////region module demo +//region module trace +/** + * Includes and configures projects related to 'forgeboot-trace' + * This module handles distributed tracing functionality. + */ include( "forgeboot-demo", - ":forgeboot-demo:forgeboot-trace-demo" + ":forgeboot-demo:forgeboot-trace-demo", + ":forgeboot-demo:forgeboot-plugin-demo", + ":forgeboot-demo:forgeboot-plugin-demo:forgeboot-plugin-demo-api", + ":forgeboot-demo:forgeboot-plugin-demo:forgeboot-plugin-demo-impl", + ":forgeboot-demo:forgeboot-plugin-demo:forgeboot-plugin-demo-server", +) +//endregion +include( + "forgeboot-plugin", + ":forgeboot-plugin:forgeboot-plugin-core", + ":forgeboot-plugin:forgeboot-plugin-spring", ) - - - -////region module security -///** -// * Includes and configures projects related to 'forgeboot-security' -// * This module handles security-related functionality. -// */ -//include( -// "forgeboot-security", -// ":forgeboot-security:forgeboot-security-core", -// -// ":forgeboot-security:forgeboot-security-authenticate", -// ":forgeboot-security:forgeboot-security-authenticate:api", -// ":forgeboot-security:forgeboot-security-authenticate:impl", -// ":forgeboot-security:forgeboot-security-authenticate:autoconfigure", -// -// ":forgeboot-security:forgeboot-security-authorize", -// ":forgeboot-security:forgeboot-security-authorize:api", -// ":forgeboot-security:forgeboot-security-authorize:impl", -// ":forgeboot-security:forgeboot-security-authorize:autoconfigure" -//) -//project(":forgeboot-security").name = "forgeboot-security-spring-boot-starter" -//project(":forgeboot-security:forgeboot-security-core").name = "forgeboot-security-core" -// -//project(":forgeboot-security:forgeboot-security-authenticate").name = -// "forgeboot-security-authenticate-spring-boot-starter" -//project(":forgeboot-security:forgeboot-security-authenticate:api").name = "forgeboot-security-authenticate-api" -//project(":forgeboot-security:forgeboot-security-authenticate:impl").name = "forgeboot-security-authenticate-impl" -//project(":forgeboot-security:forgeboot-security-authenticate:autoconfigure").name = -// "forgeboot-security-authenticate-autoconfigure" -// -//project(":forgeboot-security:forgeboot-security-authorize").name = "forgeboot-security-authorize-spring-boot-starter" -//project(":forgeboot-security:forgeboot-security-authorize:api").name = "forgeboot-security-authorize-api" -//project(":forgeboot-security:forgeboot-security-authorize:impl").name = "forgeboot-security-authorize-impl" -//project(":forgeboot-security:forgeboot-security-authorize:autoconfigure").name = -// "forgeboot-security-authorize-autoconfigure" -// -////endregion //region module cache include(