AOT
提前优化简介
AOT(Ahead of Time Optimizations)
AOT是一种构建时优化机制,主要针对GraalVM Native Image等原生镜像编译场景,通过在编译期分析和生成代码,减少运行时的反射、资源加载和动态连接等;从而实现更快的启动时间、更低的内存占用和更好的性能。
Spring AOT设计的核心概念为 静态化一切可静态化的部分:在构建时模拟ApplicationContext的刷新过程,提前做出运行时决策(Bean发现、条件判断),并生成优化的代码和元数据。避免运行时的动态扫描和反射调用,尤其适用于固定classpath的环境。
关键组件
- ApplicationContextAotGenerator:AOT引擎的入口点。它接收一个 GenericApplicationContext 和 GenerationContext,负责协调整个处理流程。
- GenerationContext:管理生成的源代码和RumtimeHints的上下文。
- RuntimeHints:收集GraalVM 所需的运行时提示,包括反射、资源加载、序列化和代理生成。
- BeanFactoryInitializationAotProcessor和BeanRegistrationAotProcessor:自定义处理器接口,用于在 AOT 阶段贡献代码生成和提示。
AOT的运行流程
- AOT专用刷新(Refresh for AOT Processing)
- 创建bean定义,但不实例化bean
- 执行BeanFactoryPostProcessor(配置解析、classpath扫描)
- 在构建时评估@Conditional和@profile条件
- 跳过大多数的BeanPostProcessor(AOP),仅处理MergedBeanDefinitionPostProcessor或SmartInstantiationAwareBeanPostProcessor
- BeanFactory初始化AOT
- 遍历所有BeanFactoryInitializationAotProcessor实现。
- 每个处理器基于当前BeanFactory状态生成代码和RuntimeHints
- 输出生成的类
- java源代码(如 __BeanDefinitions 类)。
- 字节码(动态代理)。
- 一个ApplicationContextInitializer的类,用来运行时初始化。
| |
AOT的限制
如无运行时 Bean 定义变更(禁止 registerSingleton)、实例供应商(lambda/method 引用)不可转换、需精确 Bean 类型等。这些设计使配置更“可预测”,但要求开发者避免动态行为。
AOT实例
AOT 将 @Configuration 等配置类转换为静态 Bean 定义,避免运行时反射。核心是通过 BeanInstanceSupplier 生成直接方法调用。
假设有一个 @Configuration 类:
| |
AOT 生成的代码(DataSourceConfiguration__BeanDefinitions 类):
| |
用BeanInstanceSupplier替换了反射调用,确保注入和创建是静态的。
自定义参与通过 BeanRegistrationAotProcessor 实现,例如 AutowiredAnnotationBeanPostProcessor 会生成注入代码。处理器需通过 META-INF/spring/aot.factories 注册,或直接实现接口(但这些 Bean 会在 AOT 时初始化,需谨慎使用)。
RuntimeHints处理
AOT和GraalVM的桥梁,用来收集不可静态分析的元数据。