---
title: "native 约束与兼容性"
---

Solon AOT / Native 对代码有一些**硬约束**和**软建议**。硬约束违反会在 AOT 或 native 构建阶段直接报错；软建议是为了让打包更顺利。写代码前先过一遍本文。


### 1、代理组件四约束（硬约束）

Solon 中被代理的 bean（如 `@Component` 且需要 AOP 增强的类），AOT 阶段会为其生成静态代理类。以下四类**不能**作为代理组件，违反会在 AOT 阶段直接抛错：

| 约束 | 报错信息 | 说明 |
| --- | --- | --- |
| 抽象类 | `Abstract classes are not supported as proxy components` | abstract 类不做代理 |
| final 类 | `Final classes are not supported as proxy components` | final 类无法继承生成代理 |
| 非 public 类 | `Not public classes are not supported as proxy components` | 包内/私有类不做代理 |
| 泛型类 | `Generic type classes are not supported as proxy components` | 带类型参数的类不做代理 |

**应对**：

* 这类 bean 如果不需要 AOP 增强，可以不加代理（如不配置拦截、不标记需要增强的注解）；
* 需要增强则必须改造成 public 非 final 非泛型非抽象类。

### 2、启动副作用约束（硬约束）

AOT 阶段会**真实启动一次应用**来收集容器信息：

- 主类 `main` 里的初始化逻辑会执行（发消息、写库、定时任务、预热缓存等）；
- 启动依赖的外部服务（DB、Redis、配置中心）在打包机上必须**可用**；
- 启动抛异常会中断 maven 打包（`SolonAotProcessor` 会把异常向上抛）。

**应对**：把启动副作用代码放进条件判断：

```java
public class DemoApp {
    public static void main(String[] args) {
        Solon.start(DemoApp.class, args, app -> {
            // 打包机上的 AOT 处理阶段，跳过有副作用的初始化
            if (NativeDetector.isNotAotRuntime()) {
                initSendMessage();
                initWarmCache();
            }
        });
    }
}
```

### 3、环境约束（硬约束）

| 阶段 | 约束 |
| --- | --- |
| `-P aot` | 任意 JDK 8+（v3.7.2 起） |
| `-P native` | GraalVM JDK 17+（native-image 组件） |
| 操作系统 | 构建机需安装对应原生工具链： <br/>macOS（Xcode Command Line Tools） <br/>Linux（gcc、glibc-devel、zlib-devel） <br/>Windows（Visual Studio Build Tools） |
| 内存 | native-image 构建较耗内存，建议构建机 ≥ 8G 可用内存 |

### 4、代码编写建议（软建议）

| 建议 | 说明 |
| --- | --- |
| 反射只作用于已登记类 | 动态反射的目标类，要么由 AOT 自动登记，要么手动登记 |
| 不依赖 `Class.forName` 动态加载业务类 | 运行期动态加载的类无法被 AOT 探测 |
| 不依赖 `ClassLoader.getResources` 扫资源 | 用 `ScanUtil` / `ResourceUtil`（native 下从 solon-resource.json 读取） |
| 不用动态编译 / 运行时字节码生成 | 换脚本引擎或表达式工具（Solon 生态的表达式组件） |
| 第三方库选型先验证 | 参考 《native 项目开发定制》 的 A/B/C/D 分类，新项目先做技术选型实验 |
| 需要序列化的类显式登记 | 方法参数/返回值会自动登记，其它 `registerSerialization` |

### 5、运行时环境探测（NativeDetector）

内核提供 `org.noear.solon.core.runtime.NativeDetector`，用于区分三种运行环境：

| 方法 | 返回 true 的场景 | 典型用途 |
| --- | --- | --- |
| `isAotRuntime()` | AOT 处理阶段（打包时启动的那次） | 跳过打包机上的副作用初始化 |
| `inNativeImage()` | native 可执行文件运行时 | 切换原生环境专属逻辑 |
| `isNotAotRuntime()` | 非 AOT 处理阶段（普通运行 + native 运行） | 与 `isAotRuntime()` 相反 |
| `notInNativeImage()` | 非 native 镜像（JVM 运行 + AOT 处理阶段） | 与 `inNativeImage()` 相反 |

常见写法：

* 普通运行时与 native 运行时行为一致 → 用 `isNotAotRuntime()`；
* 仅 native 才有的优化 → 用 `inNativeImage()`。
