### 兼容说明

这个版本默认依赖包（主要是指 solon-lib 和 solon-web ），配置增强和序列化的插件由 `snack3` 切换为 `snack4` （`snack3` 的适配仍可使用）

<mark>兼容问题1：</mark>

* 启用 EggG 作为类的元信息管理（如果有兼容问题，可暂时退回 v3.6.4）

<mark>兼容问题2：</mark>

* `snack3` 与 `snack4` 并不兼容，但是可以共存（部分类名相同，要注意包名的区分）。
  * `snack3` 的类包名为：`org.noear.snack.*`，maven依赖包为：`org.noear:snack3`
  * `snack4` 的类包名为：`org.noear.snack4.*`，maven依赖包为：`org.noear:snack4`
* 如果要继续使用 `snack3` 
  * 排除 `solon-config-snack4` 和 `solon-serialization-snack4`
  * 引入 `solon-config-snack3` 和 `solon-serialization-snack3`
* 如果已使用别的序列化插件
  * 要排除 `solon-serialization-snack4`（之前是排除 `solon-serialization-snack3`）
* 如果有其它依赖包依赖了 `snack3`
  * 也可单独再引入 `org.noear:snack3`
* `solon-config-snack4` 的潜在可能影响
  * snack4 的反序列化注入更严格，比如：字符串单值 "xx" 不能注入给 `List<String>` 集合（snack3 则是可以）。//后续会完善这种兼容性

`snack3` 用得好好的，为什么要换 `snack4` ？

* 首先要说明一下，solon 是个很开放的架构基座。也可以完全不用 `snack3`
* 那为什么要换？`snack3` 的架构陈旧，扩展无力。无法作为下一代 Solon v4.0 的伴侣。
* 为什么要用 `snack？`，因为可以更好的为 Solon 提供定制响应。
* `snack4` 由 AI 协助，历时半年重构完成。并通过了已有的 snack3 和 solon 相关单测。

<mark>兼容问题3:</mark>

* 所有 `solon.xxx` 和 `nami.xxx` 的依赖包不再发布（v2.9 时声明弃用），请改用 `solon-xxx` 风格的包
* 如果有第三方包仍依赖 `solon.xxx`，可排除后引入对应的 `solon-xxx`


<mark>兼容问题4:</mark>

* 控制器方法返回 `String` 时，默认 content-type 改为 `text/plain`。
  * 可以使用 `@Produces` 注解，按需指定
  * 之前有 json 插件引入时，默认为 `application/json` （有些人反对，认为不合理）。//确实也不合理，尤其在 MCP 开发时，对  content-type 很是敏感。


部分弃用对照表：

| 标为弃用 | 新启用 | 备注 |
| -------- | -------- | -------- |
| `app.chains().getInterceptorNodes()`     | `app.chains().getRouterInterceptorNodes()`     | 语义更清晰     |
| `app.chains().addInterceptor()`              | `app.chains().addRouterInterceptor()`     | 语义更清晰     |
| `app.chains().addInterceptorIfAbsent()`  | `app.chains().addRouterInterceptorIfAbsent()`     | 语义更清晰     |
| `app.chains().removeInterceptor()`        | `app.chains().removeRouterInterceptor()`     | 语义更清晰     |

ps: v3.7.0 时旧接口被移除了；v3.7.2-SNAPSHOT 已恢复

### 具体更新



* 升级 snack3 切换为 snack4
* 新增 solon-config-snack3 插件
* 新增 solon-config-snack4 插件
* 添加 solon preStop 方法名（替代 prestop），后者标为弃用。两者都可用
* 添加 solon Router:addPathPrefix(path, tester) 方法
* 添加 solon Context:localPort() 方法
* 添加 solon-server-smarthttp 有 tomcat 时的启动控制
* 优化 solon-web-staticfiles StaticResourceHandler 的 Cache-Control 处理（允许外部设定并优先）
* 优化 solon-ai-core ToolSchemaUtil:paramOf 方法，增加泛型支持
* 优化 solon-ai-core ToolSchemaUtil:outputSchema 泛型处理
* 调整 solon-config-plus 标为弃用，由 solon-config-snack3 或 solon-config-snack4 替代
* 调整 solon-net WebSocket:remoteAddress, localAddress 移除 throws IOException
* 调整 solon ActionLoader, ActionLoaderFactory 内部接口设计
* 调整 solon RouterWrapper 标为弃用，功能转到 Router 接口上
* 调整 solon ChainManager:addInterceptor （内部接口）更名为 addRouterInterceptor 强化语义
* 调整 solon 不再对 remoting 注册作 mapping 限制（改成跟控制器一样的策略）
* 调整 solon Router:getBy 更名为 findBy （前者标为弃用），避免下 get 疑似冲突
* 调整 solon-server 允许不输出 content-type 
* 修复 solon-ai parseToolCall 接收 stream 中间消息时可能会异常（添加 hasNestedJsonBlock 检测）
* 修复 solon-ai-mcp 可能出现 Unknown media type 错误（取消 request.contentType 空设置）
* 移除 solon.xxx 和 nami.xxx 风格的发布包
* 启用 eggg 作为类元信息构建机制
* redisx 升为 1.8.2（snack3 切换为 snack4）
* wood 升为 1.4.2（snack3 切换为 snack4）
* snack4 升为 4.0.8
* log4j 升为 2.25.2
* logback 升为 1.3.16
* jakarta.logback 升为 1.5.20
* micrometer 升为 1.15.5 
* opentelemetry 升为 1.55.0
* socketd 升为 2.5.20
* smartsocket 升为 1.7.4
* smarthttp 升为 2.5.16
* undertow 升为 2.2.38.Final



快捷组合包调整情况（如果有排除，别搞错了）：


| 快捷组合包      | 调整情况                                                           |
|------------|----------------------------------------------------------------|
| solon-lib  | 使用 solon-config-snack4 替代 solon-config-snack3                  |
| solon-web  | 使用 solon-serialization-snack4 替代    solon-serialization-snack3 |



关于配置的几个插件说明（solon 是个很开放的架构基座）：


| 插件         | 描述         | 备注 |
| -------- | -------- | -------- |
| `solon-config-yaml`        | 用于加载 yaml 和 json 的属性配置                                           |      |
| `solon-config-snack3`     | 提供 `@Inject("${xxx}")` 和 `@BindProps("xxx")`  属性注入或填充支持   | v3.7.0 后弃用     |
| `solon-config-snack4`     | 提供 `@Inject("${xxx}")` 和 `@BindProps("xxx")`  属性注入或填充支持     |      |

