The aot.factories and spring.factories files serve fundamental different purposes in Spring Boot 3. While spring.factories was traditionally used for auto-configuration, the newer aot.factories plays a critical role in Ahead-of-Time (AOT) compilation scenarios.
Evolution of Configuraton Loading
In Spring Boot 3, the auto-configuration mechanism has migrated from META-INF/spring.factories to META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. This change represents a more structured approach to configuration loading.
Practical Implementation Differences
Consider this example of auto-configuration in Spring Boot 3:
@AutoConfiguration(after = { RestClientAutoConfiguration.class, RetryAutoConfiguration.class })
@ConditionalOnClass(CustomApi.class)
@EnableConfigurationProperties({ ConnectionProperties.class, ChatProperties.class })
public class CustomAutoConfiguration {
// Configuration implementation
}
While traditional auto-configuration works at runtime, AOT processing requires additional metadata to support native image compilation.
GraalVM and Native Image Compilation
The aot.factories file is specifically designed to support GraalVM's native image compilation process. This enables Spring applications to be compiled into standalone executables that don't require a JVM.
Configuration for Native Compilation
Here's an example Maven configuration for native image compilation:
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<configuration>
<imageName>${project.artifactId}</imageName>
<mainClass>com.example.AppMain</mainClass>
<buildArgs>
--no-fallback
</buildArgs>
</configuration>
</plugin>
RuntimeHints Integration
The aot.factories file works in conjunction with Spring's RuntimeHints API to handle dynamic features in AOT compilation:
org.springframework.aot.hint.RuntimeHintsRegistrar=\
com.example.config.CustomRuntimeHints
org.springframework.beans.factory.aot.BeanRegistrationAotProcessor=\
com.example.processor.CustomProcessor
This mechanism ensures that reflection, resource loading, and other dynamic features are properly registered during compilation.
Considerations and Limitations
While GraalVM native images offer significant startup performance benefits, there are important constraints:
- Reduced support for dynamic features like reflection
- Compatibility challenges with older JDK versions
- Longer build times for native compilation