Solon v4.0.5

native 约束与兼容性

</> markdown
2026年8月12日 上午11:24:42

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

1、代理组件四约束(硬约束)

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

约束报错信息说明
抽象类Abstract classes are not supported as proxy componentsabstract 类不做代理
final 类Final classes are not supported as proxy componentsfinal 类无法继承生成代理
非 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 会把异常向上抛)。

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

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 nativeGraalVM JDK 17+(native-image 组件)
操作系统构建机需安装对应原生工具链:
macOS(Xcode Command Line Tools)
Linux(gcc、glibc-devel、zlib-devel)
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()