mirror of
https://github.moeyy.xyz/https://github.com/GeWuYou/forgeboot
synced 2025-10-27 19:12:10 +08:00
Merge branch 'feature/6-support-plugin-modules' into 'main'
feat(plugin) 添加插件支持 Closes #6 See merge request gewuyou/forgeboot!11
This commit is contained in:
commit
61e5ea3130
58
README.md
58
README.md
@ -1,23 +1,51 @@
|
|||||||
# forgeboot
|
# forgeboot
|
||||||
|
|
||||||
This project uses [Gradle](https://gradle.org/).
|
多模块 Spring Boot 工具与 Starter 集合
|
||||||
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:
|
|
||||||
|
|
||||||
* 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`).
|
`forgeboot` 是一套面向 Spring Boot 的通用基础库,包含 Banner、缓存、上下文传播、核心工具、国际化、
|
||||||
This is the suggested way to use Gradle in production projects.
|
调用链追踪、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
|
1. 克隆仓库:
|
||||||
and both a build cache and a configuration cache (see `gradle.properties`).
|
```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
|
||||||
|
|||||||
@ -117,7 +117,19 @@ object Modules {
|
|||||||
"${AUTHORIZE}:forgeboot-security-authorize-autoconfigure"
|
"${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{
|
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"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
57
forgeboot-banner/README.md
Normal file
57
forgeboot-banner/README.md
Normal file
@ -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
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.gewuyou</groupId>
|
||||||
|
<artifactId>forgeboot-banner</artifactId>
|
||||||
|
<version>${version}</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
使用 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
|
||||||
54
forgeboot-cache/README.md
Normal file
54
forgeboot-cache/README.md
Normal file
@ -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
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.gewuyou</groupId>
|
||||||
|
<artifactId>forgeboot-cache-spring-boot-starter</artifactId>
|
||||||
|
<version>${version}</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
使用 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
|
||||||
103
forgeboot-context/README.md
Normal file
103
forgeboot-context/README.md
Normal file
@ -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
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.gewuyou</groupId>
|
||||||
|
<artifactId>forgeboot-context-spring-boot-starter</artifactId>
|
||||||
|
<version>${version}</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
使用 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 改进本模块!
|
||||||
40
forgeboot-core/README.md
Normal file
40
forgeboot-core/README.md
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# forgeboot-core
|
||||||
|
|
||||||
|
通用核心库
|
||||||
|
|
||||||
|
## 简介
|
||||||
|
|
||||||
|
`forgeboot-core` 包含项目中通用的扩展、工具与序列化支持,例如通用枚举处理、序列化接口、基础配置等。
|
||||||
|
|
||||||
|
## 核心功能
|
||||||
|
|
||||||
|
- **forgeboot-core-extension**:公共扩展函数、集合工具类等。
|
||||||
|
- **forgeboot-core-serialization**:Jackson/Kotlin 序列化自定义注册与模块。
|
||||||
|
|
||||||
|
## 引入依赖
|
||||||
|
|
||||||
|
Maven:
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.gewuyou</groupId>
|
||||||
|
<artifactId>forgeboot-core</artifactId>
|
||||||
|
<version>${version}</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
使用 Gradle:
|
||||||
|
```groovy
|
||||||
|
implementation "io.github.gewuyou:forgeboot-core:${version}"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 快速开始
|
||||||
|
|
||||||
|
在 Spring Boot 中引入后,自动注册序列化模块,可直接使用扩展函数。
|
||||||
|
|
||||||
|
## 构建
|
||||||
|
```bash
|
||||||
|
./gradlew :forgeboot-core:build
|
||||||
|
```
|
||||||
|
|
||||||
|
## 许可
|
||||||
|
|
||||||
|
Apache-2.0
|
||||||
28
forgeboot-demo/README.md
Normal file
28
forgeboot-demo/README.md
Normal file
@ -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
|
||||||
3
forgeboot-demo/forgeboot-plugin-demo/.gitattributes
vendored
Normal file
3
forgeboot-demo/forgeboot-plugin-demo/.gitattributes
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/gradlew text eol=lf
|
||||||
|
*.bat text eol=crlf
|
||||||
|
*.jar binary
|
||||||
40
forgeboot-demo/forgeboot-plugin-demo/.gitignore
vendored
Normal file
40
forgeboot-demo/forgeboot-plugin-demo/.gitignore
vendored
Normal file
@ -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
|
||||||
5
forgeboot-demo/forgeboot-plugin-demo/build.gradle.kts
Normal file
5
forgeboot-demo/forgeboot-plugin-demo/build.gradle.kts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
dependencies {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
3
forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-api/.gitattributes
vendored
Normal file
3
forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-api/.gitattributes
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/gradlew text eol=lf
|
||||||
|
*.bat text eol=crlf
|
||||||
|
*.jar binary
|
||||||
40
forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-api/.gitignore
vendored
Normal file
40
forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-api/.gitignore
vendored
Normal file
@ -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
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
plugins {
|
||||||
|
alias(libs.plugins.kotlin.kapt)
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
kapt(libs.org.pf4j)
|
||||||
|
implementation(libs.org.pf4j)
|
||||||
|
}
|
||||||
@ -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
|
||||||
|
}
|
||||||
@ -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
|
||||||
|
}
|
||||||
3
forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/.gitattributes
vendored
Normal file
3
forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/.gitattributes
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/gradlew text eol=lf
|
||||||
|
*.bat text eol=crlf
|
||||||
|
*.jar binary
|
||||||
40
forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/.gitignore
vendored
Normal file
40
forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-impl/.gitignore
vendored
Normal file
@ -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
|
||||||
@ -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)
|
||||||
|
}
|
||||||
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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!"
|
||||||
|
}
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
pluginId: simple-greeting
|
||||||
|
version: 1.0.0
|
||||||
|
pluginClass: com.gewuyou.forgeboot.plugin.demo.impl.SimpleGreetingPlugin
|
||||||
|
pluginDescription: A greeting plugin
|
||||||
3
forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/.gitattributes
vendored
Normal file
3
forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/.gitattributes
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/gradlew text eol=lf
|
||||||
|
*.bat text eol=crlf
|
||||||
|
*.jar binary
|
||||||
40
forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/.gitignore
vendored
Normal file
40
forgeboot-demo/forgeboot-plugin-demo/forgeboot-plugin-demo-server/.gitignore
vendored
Normal file
@ -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
|
||||||
@ -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)
|
||||||
|
}
|
||||||
Binary file not shown.
@ -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<String>) {
|
||||||
|
runApplication<ForgebootPluginDemoServerApplication>(*args)
|
||||||
|
}
|
||||||
@ -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)
|
||||||
|
}
|
||||||
@ -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 = "服务器问候"
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
forgeboot:
|
||||||
|
plugin:
|
||||||
|
path: .\forgeboot-demo\forgeboot-plugin-demo\forgeboot-plugin-demo-server\plugins
|
||||||
49
forgeboot-i18n/README.md
Normal file
49
forgeboot-i18n/README.md
Normal file
@ -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
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.gewuyou</groupId>
|
||||||
|
<artifactId>forgeboot-i18n-spring-boot-starter</artifactId>
|
||||||
|
<version>${version}</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
使用 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
|
||||||
3
forgeboot-plugin/.gitattributes
vendored
Normal file
3
forgeboot-plugin/.gitattributes
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/gradlew text eol=lf
|
||||||
|
*.bat text eol=crlf
|
||||||
|
*.jar binary
|
||||||
40
forgeboot-plugin/.gitignore
vendored
Normal file
40
forgeboot-plugin/.gitignore
vendored
Normal file
@ -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
|
||||||
4
forgeboot-plugin/build.gradle.kts
Normal file
4
forgeboot-plugin/build.gradle.kts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
dependencies {
|
||||||
|
|
||||||
|
}
|
||||||
3
forgeboot-plugin/forgeboot-plugin-core/.gitattributes
vendored
Normal file
3
forgeboot-plugin/forgeboot-plugin-core/.gitattributes
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/gradlew text eol=lf
|
||||||
|
*.bat text eol=crlf
|
||||||
|
*.jar binary
|
||||||
40
forgeboot-plugin/forgeboot-plugin-core/.gitignore
vendored
Normal file
40
forgeboot-plugin/forgeboot-plugin-core/.gitignore
vendored
Normal file
@ -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
|
||||||
9
forgeboot-plugin/forgeboot-plugin-core/build.gradle.kts
Normal file
9
forgeboot-plugin/forgeboot-plugin-core/build.gradle.kts
Normal file
@ -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")
|
||||||
|
}
|
||||||
@ -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<T : PluginDescriptor, R>(
|
||||||
|
private val metadataClass: Class<R>,
|
||||||
|
private val descriptorMapper: YamlPluginDescriptorMapper<T, R>,
|
||||||
|
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<R>(reader)
|
||||||
|
?: throw PluginRuntimeException("Failed to load YAML from: $path")
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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<T : PluginDescriptor>(
|
||||||
|
protected val descriptorClass: Class<T>,
|
||||||
|
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<T>(reader)
|
||||||
|
?: throw PluginRuntimeException("Failed to load YAML from: $path")
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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<T : PluginDescriptor, R> {
|
||||||
|
/**
|
||||||
|
* 将给定的源数据对象映射为插件描述符实例。
|
||||||
|
*
|
||||||
|
* @param metadata 提供映射所需数据的源对象
|
||||||
|
* @return 返回映射生成的插件描述符对象(T类型)
|
||||||
|
*/
|
||||||
|
fun mapFrom(metadata: R): T
|
||||||
|
}
|
||||||
3
forgeboot-plugin/forgeboot-plugin-spring/.gitattributes
vendored
Normal file
3
forgeboot-plugin/forgeboot-plugin-spring/.gitattributes
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/gradlew text eol=lf
|
||||||
|
*.bat text eol=crlf
|
||||||
|
*.jar binary
|
||||||
37
forgeboot-plugin/forgeboot-plugin-spring/.gitignore
vendored
Normal file
37
forgeboot-plugin/forgeboot-plugin-spring/.gitignore
vendored
Normal file
@ -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/
|
||||||
11
forgeboot-plugin/forgeboot-plugin-spring/build.gradle.kts
Normal file
11
forgeboot-plugin/forgeboot-plugin-spring/build.gradle.kts
Normal file
@ -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")
|
||||||
|
}
|
||||||
@ -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<*>
|
||||||
|
}
|
||||||
@ -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<*>
|
||||||
|
}
|
||||||
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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<Path>,
|
||||||
|
) : SpringPluginManager(pluginsRoots) {
|
||||||
|
override fun createPluginDescriptorFinder(): CompoundPluginDescriptorFinder {
|
||||||
|
return CompoundPluginDescriptorFinder()
|
||||||
|
.add(YamlPluginDescriptorFinder())
|
||||||
|
.add(PropertiesPluginDescriptorFinder())
|
||||||
|
.add(ManifestPluginDescriptorFinder())
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
com.gewuyou.forgeboot.plugin.spring.config.PluginSpringAutoConfiguration
|
||||||
84
forgeboot-trace/README.md
Normal file
84
forgeboot-trace/README.md
Normal file
@ -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
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.gewuyou</groupId>
|
||||||
|
<artifactId>forgeboot-trace-spring-boot-starter</artifactId>
|
||||||
|
<version>${version}</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
使用 Gradle:
|
||||||
|
|
||||||
|
```groovy
|
||||||
|
implementation "io.github.gewuyou:forgeboot-trace-spring-boot-starter:${version}"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 快速开始
|
||||||
|
|
||||||
|
1. 引入依赖并启用自动配置(Spring Boot 自动生效)
|
||||||
|
|
||||||
|
2. 在日志配置中添加 traceId(以 logback 为例):
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level traceId=%X{traceId} %logger{36} - %msg%n</pattern>
|
||||||
|
```
|
||||||
|
|
||||||
|
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 改进本模块!
|
||||||
47
forgeboot-webmvc/README.md
Normal file
47
forgeboot-webmvc/README.md
Normal file
@ -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
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.gewuyou</groupId>
|
||||||
|
<artifactId>forgeboot-webmvc-spring-boot-starter</artifactId>
|
||||||
|
<version>${version}</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
使用 Gradle:
|
||||||
|
```groovy
|
||||||
|
implementation "io.github.gewuyou:forgeboot-webmvc-spring-boot-starter:${version}"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 快速开始
|
||||||
|
|
||||||
|
- 在 `application.yml` 中配置各模块开关和策略。
|
||||||
|
- 使用 `BaseResult<T>` 或 `PageResult<T>` 封装返回值。
|
||||||
|
- Controller 中使用 `@ApiVersion`, `@Validated` 等注解。
|
||||||
|
|
||||||
|
## 构建
|
||||||
|
```bash
|
||||||
|
./gradlew :forgeboot-webmvc:build
|
||||||
|
```
|
||||||
|
|
||||||
|
## 许可
|
||||||
|
|
||||||
|
Apache-2.0
|
||||||
197
forgeboot-webmvc/dto/README.md
Normal file
197
forgeboot-webmvc/dto/README.md
Normal file
@ -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
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.gewuyou</groupId>
|
||||||
|
<artifactId>forgeboot-webmvc-dto</artifactId>
|
||||||
|
<version>${version}</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
使用 Gradle:
|
||||||
|
|
||||||
|
```groovy
|
||||||
|
implementation "io.github.gewuyou:forgeboot-webmvc-dto:${version}"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 快速开始
|
||||||
|
|
||||||
|
### ✅ 统一响应使用示例
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
@GetMapping("/hello")
|
||||||
|
fun hello(): R<String> {
|
||||||
|
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 <T> toPageResult(page: Page<T>): PageResult<T> {
|
||||||
|
return PageResult.of(page)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
控制器示例:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
@GetMapping("/users")
|
||||||
|
fun listUsers(request: UserPageRequest): PageResult<UserDTO> {
|
||||||
|
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<ProductDTO> {
|
||||||
|
val (spec, pageRequest) = request.toJpaQuery<ProductEntity>()
|
||||||
|
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<ProductDTO> {
|
||||||
|
val (spec, pageRequest) = request.toJpaQuery<ProductEntity>()
|
||||||
|
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 改进本模块!
|
||||||
@ -9,7 +9,6 @@ dependencies {
|
|||||||
compileOnly(libs.jackson.annotations)
|
compileOnly(libs.jackson.annotations)
|
||||||
compileOnly(libs.springBootStarter.jpa)
|
compileOnly(libs.springBootStarter.jpa)
|
||||||
compileOnly(libs.springBootStarter.validation)
|
compileOnly(libs.springBootStarter.validation)
|
||||||
compileOnly(libs.org.mapstruct)
|
|
||||||
}
|
}
|
||||||
i18nKeyGen {
|
i18nKeyGen {
|
||||||
rootPackage.set("com.gewuyou.forgeboot.webmvc.dto.i18n")
|
rootPackage.set("com.gewuyou.forgeboot.webmvc.dto.i18n")
|
||||||
|
|||||||
@ -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<S, T> {
|
|
||||||
/**
|
|
||||||
* 将 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<S>): List<T>
|
|
||||||
}
|
|
||||||
@ -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 <Entity> 实体类类型
|
|
||||||
* @param <Dto> 数据传输对象类型
|
|
||||||
*
|
|
||||||
* @since 2025-05-30 22:53:35
|
|
||||||
* @author gewuyou
|
|
||||||
*/
|
|
||||||
interface ConversionMapper<Entity, Dto> {
|
|
||||||
/**
|
|
||||||
* 将实体对象转换为对应的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<Entity>): List<Dto>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将DTO对象列表转换为对应的实体对象列表
|
|
||||||
*
|
|
||||||
* @param dtoList 需要转换的DTO对象列表
|
|
||||||
* @return 转换后的实体对象列表
|
|
||||||
*/
|
|
||||||
fun toEntityList(dtoList: List<Dto>): List<Entity>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 使用非空属性对实体进行部分更新
|
|
||||||
*
|
|
||||||
* 注意:此操作不会覆盖实体中为空的属性
|
|
||||||
*
|
|
||||||
* @param dto 需要用于更新的DTO对象
|
|
||||||
* @param entity 需要被更新的实体对象
|
|
||||||
*/
|
|
||||||
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
|
|
||||||
fun partialUpdate(dto: Dto, @MappingTarget entity: Entity)
|
|
||||||
}
|
|
||||||
117
forgeboot-webmvc/spec/README.md
Normal file
117
forgeboot-webmvc/spec/README.md
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
# forgeboot-webmvc-spec
|
||||||
|
|
||||||
|
> 🧩 Web 项目通用 CRUD 接口规范模块,封装 Repository 与 Service 层的标准增删改查接口与默认实现,简化重复代码。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧩 简介
|
||||||
|
|
||||||
|
`forgeboot-webmvc-spec` 是 ForgeBoot 提供的统一接口规范模块,旨在为常见的 Web 开发提供可复用的 Repository 和 Service 层增删改查基础接口及实现模板。
|
||||||
|
|
||||||
|
通过继承和组合该模块中的接口和基类,可以快速构建具有一致风格的业务组件,提升开发效率、降低重复代码、统一项目结构。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✨ 核心功能
|
||||||
|
|
||||||
|
- ✅ `CrudRepositorySpec<T, ID>`:通用 Repository 接口规范(继承自 `JpaRepository`)
|
||||||
|
- ✅ `CrudServiceSpec<T, ID>`:业务层接口标准化定义
|
||||||
|
- ✅ `CrudServiceImplSpec<T, ID>`:默认 Service 实现(依赖 Repository)
|
||||||
|
- ✅ 泛型支持 Entity 类型与主键类型的自动推导
|
||||||
|
- ✅ 与 DTO 模块 (`forgeboot-webmvc-dto`) 无缝协作
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📦 引入依赖
|
||||||
|
|
||||||
|
使用 Maven:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.gewuyou</groupId>
|
||||||
|
<artifactId>forgeboot-webmvc-spec</artifactId>
|
||||||
|
<version>${version}</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
使用 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<Product, Long>
|
||||||
|
```
|
||||||
|
|
||||||
|
### ✅ 创建 Service 接口
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
interface ProductService : CrudServiceSpec<Product, Long>
|
||||||
|
```
|
||||||
|
|
||||||
|
### ✅ 创建默认实现类
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
@Service
|
||||||
|
class ProductServiceImpl(
|
||||||
|
override val repository: ProductRepository
|
||||||
|
) : CrudServiceImplSpec<Product, Long>(), 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 改进本模块!
|
||||||
@ -17,6 +17,10 @@ slf4j-version = "2.0.17"
|
|||||||
map-struct-version="1.6.3"
|
map-struct-version="1.6.3"
|
||||||
caffeine-version="3.2.1"
|
caffeine-version="3.2.1"
|
||||||
redisson-version="3.50.0"
|
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]
|
[libraries]
|
||||||
kotlinGradlePlugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin-version" }
|
kotlinGradlePlugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin-version" }
|
||||||
kotlinxDatetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinxDatetime-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" }
|
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-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-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" }
|
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" }
|
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" }
|
reactor-core = { group = "io.projectreactor", name = "reactor-core" }
|
||||||
#org
|
#org
|
||||||
org-mapstruct = { group = "org.mapstruct", name = "mapstruct", version.ref = "map-struct-version" }
|
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
|
# Libraries can be bundled together for easier import
|
||||||
# jwt
|
# jwt
|
||||||
jjwt-api = { module = "io.jsonwebtoken:jjwt-api", version.ref = "jjwt-version" }
|
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" }
|
jjwt-jackson = { module = "io.jsonwebtoken:jjwt-jackson", version.ref = "jjwt-version" }
|
||||||
# com
|
# com
|
||||||
com-github-benManes-caffeine = { module = "com.github.ben-manes.caffeine:caffeine",version.ref = "caffeine-version" }
|
com-github-benManes-caffeine = { module = "com.github.ben-manes.caffeine:caffeine",version.ref = "caffeine-version" }
|
||||||
|
# io
|
||||||
|
|
||||||
[bundles]
|
[bundles]
|
||||||
kotlinxEcosystem = ["kotlinxDatetime", "kotlinxSerialization", "kotlinxCoroutines-core"]
|
kotlinxEcosystem = ["kotlinxDatetime", "kotlinxSerialization", "kotlinxCoroutines-core"]
|
||||||
jacksonAll = [
|
jacksonAll = [
|
||||||
|
|||||||
@ -136,50 +136,25 @@ project(":forgeboot-trace:forgeboot-trace-impl").name = "forgeboot-trace-impl"
|
|||||||
project(":forgeboot-trace:forgeboot-trace-autoconfigure").name = "forgeboot-trace-autoconfigure"
|
project(":forgeboot-trace:forgeboot-trace-autoconfigure").name = "forgeboot-trace-autoconfigure"
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
////region module demo
|
//region module trace
|
||||||
|
/**
|
||||||
|
* Includes and configures projects related to 'forgeboot-trace'
|
||||||
|
* This module handles distributed tracing functionality.
|
||||||
|
*/
|
||||||
include(
|
include(
|
||||||
"forgeboot-demo",
|
"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
|
//region module cache
|
||||||
include(
|
include(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user