CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-springframework--spring-core

Spring Framework Core - IoC Container and Dependency Injection

Pending
Overview
Eval results
Files

aot-optimization.mddocs/

AOT Optimization and Native Images

Spring Core provides comprehensive Ahead-of-Time (AOT) compilation support that enables applications to be compiled to native images using GraalVM. This includes runtime hints registration, reflection optimization, and resource bundling for optimal native image performance.

AOT Detection and Configuration

Spring provides utilities to detect when AOT optimizations are available and should be used.

AotDetector Utility

public final class AotDetector {
    public static final String AOT_ENABLED = "spring.aot.enabled";
    
    public static boolean useGeneratedArtifacts();
    
    // Private constructor - utility class
}

Usage Examples

// Check if AOT optimizations should be used
boolean shouldUseAot = AotDetector.useGeneratedArtifacts();
if (shouldUseAot) {
    // Use pre-compiled AOT optimizations
    loadPreCompiledBeans();
} else {
    // Use standard runtime reflection-based initialization
    loadStandardBeans();
}

// Enable AOT via system property
System.setProperty("spring.aot.enabled", "true");

// Or via environment variable
// SPRING_AOT_ENABLED=true

// Conditional logic based on AOT availability
@Component
public class ConditionalService {
    
    public ConditionalService() {
        if (AotDetector.useGeneratedArtifacts()) {
            initializeForNativeImage();
        } else {
            initializeForJvm();
        }
    }
}

Runtime Hints System

The runtime hints system allows applications to register metadata that helps AOT compilation tools understand which classes, methods, fields, and resources need to be available at runtime.

RuntimeHints Class

public final class RuntimeHints {
    public ReflectionHints reflection();
    public ResourceHints resources();
    public SerializationHints serialization();
    public ProxyHints proxies();
    public JniHints jni();
}

RuntimeHintsRegistrar Interface

@FunctionalInterface
public interface RuntimeHintsRegistrar {
    void registerHints(RuntimeHints hints, ClassLoader classLoader);
}

Usage Examples

// Implement custom runtime hints registrar
public class MyApplicationRuntimeHints implements RuntimeHintsRegistrar {
    
    @Override
    public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
        // Register reflection hints
        hints.reflection()
            .registerType(MyService.class, MemberCategory.INVOKE_PUBLIC_METHODS)
            .registerType(MyEntity.class, MemberCategory.DECLARED_FIELDS)
            .registerConstructor(MyController.class.getConstructor(MyService.class), ExecutableMode.INVOKE);
        
        // Register resource hints
        hints.resources()
            .registerPattern("templates/*.html")
            .registerPattern("static/css/*.css")
            .registerResourceBundle("messages");
        
        // Register serialization hints
        hints.serialization()
            .registerType(MyDto.class)
            .registerType(MyResponse.class);
        
        // Register proxy hints
        hints.proxies()
            .registerJdkProxy(MyInterface.class, AnotherInterface.class);
    }
}

// Register hints programmatically
RuntimeHints hints = new RuntimeHints();
MyApplicationRuntimeHints registrar = new MyApplicationRuntimeHints();
registrar.registerHints(hints, getClass().getClassLoader());

Reflection Hints

The reflection hints system provides fine-grained control over which classes, methods, fields, and constructors should be available for reflection in native images.

ReflectionHints Class

public final class ReflectionHints {
    // Type registration
    public Builder registerType(Class<?> type, MemberCategory... memberCategories);
    public Builder registerType(TypeReference type, MemberCategory... memberCategories);
    public Builder registerTypeIfPresent(ClassLoader classLoader, String typeName, MemberCategory... memberCategories);
    
    // Constructor registration
    public Builder registerConstructor(Constructor<?> constructor, ExecutableMode executableMode);
    public Builder registerConstructor(TypeReference type, List<TypeReference> parameterTypes, ExecutableMode executableMode);
    
    // Method registration
    public Builder registerMethod(Method method, ExecutableMode executableMode);
    public Builder registerMethod(TypeReference type, String methodName, List<TypeReference> parameterTypes, ExecutableMode executableMode);
    
    // Field registration
    public Builder registerField(Field field);
    public Builder registerField(TypeReference type, String fieldName);
    
    // Query methods
    public Stream<TypeHint> typeHints();
    public TypeHint getTypeHint(Class<?> type);
    public TypeHint getTypeHint(TypeReference type);
}

public enum MemberCategory {
    INTROSPECT_PUBLIC_CONSTRUCTORS,
    INTROSPECT_DECLARED_CONSTRUCTORS, 
    INVOKE_PUBLIC_CONSTRUCTORS,
    INVOKE_DECLARED_CONSTRUCTORS,
    INTROSPECT_PUBLIC_METHODS,
    INTROSPECT_DECLARED_METHODS,
    INVOKE_PUBLIC_METHODS,
    INVOKE_DECLARED_METHODS,
    INTROSPECT_PUBLIC_FIELDS,
    INTROSPECT_DECLARED_FIELDS,
    PUBLIC_FIELDS,
    DECLARED_FIELDS
}

public enum ExecutableMode {
    INTROSPECT,
    INVOKE
}

Usage Examples

// Register comprehensive reflection hints
RuntimeHints hints = new RuntimeHints();
ReflectionHints reflection = hints.reflection();

// Register entity classes for full reflection access
reflection.registerType(User.class,
    MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
    MemberCategory.DECLARED_FIELDS,
    MemberCategory.INVOKE_PUBLIC_METHODS);

// Register service classes for method invocation
reflection.registerType(UserService.class, MemberCategory.INVOKE_PUBLIC_METHODS);

// Register specific constructors
Constructor<UserController> constructor = UserController.class.getConstructor(UserService.class);
reflection.registerConstructor(constructor, ExecutableMode.INVOKE);

// Register specific methods
Method findByIdMethod = UserService.class.getMethod("findById", Long.class);
reflection.registerMethod(findByIdMethod, ExecutableMode.INVOKE);

// Register fields for serialization frameworks
Field userIdField = User.class.getDeclaredField("id");
reflection.registerField(userIdField);

// Conditional registration based on classpath presence
reflection.registerTypeIfPresent(classLoader, 
    "com.fasterxml.jackson.databind.ObjectMapper",
    MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS,
    MemberCategory.INVOKE_PUBLIC_METHODS);

// Register generic types
reflection.registerType(TypeReference.of("com.example.GenericService<java.lang.String>"),
    MemberCategory.INVOKE_PUBLIC_METHODS);

// Check registered hints
TypeHint userHint = reflection.getTypeHint(User.class);
if (userHint != null) {
    boolean hasConstructorHints = !userHint.constructorHints().isEmpty();
    boolean hasMethodHints = !userHint.methodHints().isEmpty();
}

Resource Hints

Resource hints specify which resources should be bundled into the native image and available at runtime.

ResourceHints Class

public final class ResourceHints {
    // Pattern-based registration
    public Builder registerPattern(String pattern);
    public Builder registerPattern(ResourcePatternHint hint);
    
    // Type-based registration
    public Builder registerType(Class<?> type);
    public Builder registerTypeIfPresent(ClassLoader classLoader, String typeName);
    
    // Resource bundle registration
    public Builder registerResourceBundle(String baseName);
    
    // Query methods
    public Stream<ResourcePatternHint> resourcePatternHints();
    public Stream<ResourceBundleHint> resourceBundleHints();
}

public final class ResourcePatternHint {
    public static ResourcePatternHint of(String pattern);
    public static ResourcePatternHint of(String pattern, Predicate<String> filter);
    
    public String getPattern();
    public Predicate<String> getFilter();
}

Usage Examples

// Register resource patterns
RuntimeHints hints = new RuntimeHints();
ResourceHints resources = hints.resources();

// Static web resources
resources.registerPattern("static/**")
         .registerPattern("templates/*.html")
         .registerPattern("css/*.css")
         .registerPattern("js/*.js");

// Configuration files
resources.registerPattern("application*.properties")
         .registerPattern("application*.yml")
         .registerPattern("config/*.xml");

// Resource bundles for internationalization
resources.registerResourceBundle("messages")
         .registerResourceBundle("validation")
         .registerResourceBundle("labels");

// Class-based resource registration (includes class and related resources)
resources.registerType(MyController.class); // Includes MyController.class and package resources
resources.registerType(MyService.class);

// Conditional resource registration
resources.registerTypeIfPresent(classLoader, "com.example.OptionalService");

// Advanced pattern with filtering
ResourcePatternHint filteredHint = ResourcePatternHint.of("data/*.json", 
    filename -> !filename.contains("test"));
resources.registerPattern(filteredHint);

// Register resources for specific packages
resources.registerPattern("com/example/templates/**")
         .registerPattern("META-INF/spring/**")
         .registerPattern("META-INF/services/**");

Serialization Hints

Serialization hints specify which classes need to be available for serialization/deserialization in native images.

SerializationHints Class

public final class SerializationHints {
    // Type registration
    public Builder registerType(Class<?> type);
    public Builder registerType(TypeReference type);
    public Builder registerTypeIfPresent(ClassLoader classLoader, String typeName);
    
    // Query methods
    public Stream<JavaSerializationHint> javaSerializationHints();
}

Usage Examples

// Register serialization hints
RuntimeHints hints = new RuntimeHints();
SerializationHints serialization = hints.serialization();

// Register DTOs and entities for JSON serialization
serialization.registerType(UserDto.class)
             .registerType(OrderDto.class)
             .registerType(ProductDto.class);

// Register domain entities
serialization.registerType(User.class)
             .registerType(Order.class)
             .registerType(Product.class);

// Register generic types
serialization.registerType(TypeReference.of("java.util.List<com.example.UserDto>"))
             .registerType(TypeReference.of("java.util.Map<java.lang.String, java.lang.Object>"));

// Conditional registration for optional dependencies
serialization.registerTypeIfPresent(classLoader, "com.example.CacheEntry");

// Register collections and common types
serialization.registerType(ArrayList.class)
             .registerType(HashMap.class)
             .registerType(LinkedHashMap.class);

Proxy Hints

Proxy hints specify which interfaces should be available for JDK dynamic proxy creation.

ProxyHints Class

public final class ProxyHints {
    // JDK proxy registration
    public Builder registerJdkProxy(Class<?>... interfaces);
    public Builder registerJdkProxy(TypeReference... interfaces);
    public Builder registerJdkProxy(JdkProxyHint hint);
    
    // Query methods
    public Stream<JdkProxyHint> jdkProxyHints();
}

Usage Examples

// Register proxy hints
RuntimeHints hints = new RuntimeHints();
ProxyHints proxies = hints.proxies();

// Register service interfaces for proxy creation
proxies.registerJdkProxy(UserService.class)
       .registerJdkProxy(OrderService.class)
       .registerJdkProxy(ProductService.class);

// Register multiple interfaces for single proxy
proxies.registerJdkProxy(MyService.class, Serializable.class, Cloneable.class);

// Register transaction proxies
proxies.registerJdkProxy(
    TypeReference.of("org.springframework.transaction.interceptor.TransactionalProxy"),
    TypeReference.of("org.springframework.aop.SpringProxy"));

// Register common Spring proxy interfaces
proxies.registerJdkProxy(
    TypeReference.of("org.springframework.aop.framework.Advised"),
    TypeReference.of("org.springframework.core.DecoratingProxy"));

Type References

Type references provide a way to specify types that may not be available on the classpath at compile time.

TypeReference Interface

public interface TypeReference {
    String getName();
    String getCanonicalName();
    String getPackageName();
    String getSimpleName();
    TypeReference getEnclosingType();
    
    // Static factory methods
    static TypeReference of(String name);
    static TypeReference of(Class<?> type);
}

Usage Examples

// Create type references for optional dependencies
TypeReference optionalType = TypeReference.of("com.example.OptionalService");
TypeReference genericType = TypeReference.of("java.util.List<java.lang.String>");
TypeReference arrayType = TypeReference.of("[Lcom.example.User;");

// Use in hints registration
RuntimeHints hints = new RuntimeHints();

hints.reflection()
     .registerType(optionalType, MemberCategory.INVOKE_PUBLIC_METHODS)
     .registerType(genericType, MemberCategory.INTROSPECT_PUBLIC_METHODS);

hints.serialization()
     .registerType(optionalType);

// Type reference utilities
String packageName = optionalType.getPackageName(); // "com.example"
String simpleName = optionalType.getSimpleName();   // "OptionalService"
String canonicalName = optionalType.getCanonicalName(); // "com.example.OptionalService"

Native Image Detection

NativeDetector Utility

public final class NativeDetector {
    public static boolean inNativeImage();
    
    // Private constructor - utility class
}

Usage Examples

// Runtime behavior adaptation for native images
public class AdaptiveService {
    
    public void initialize() {
        if (NativeDetector.inNativeImage()) {
            // Native image optimized initialization
            initializeForNativeImage();
        } else {
            // JVM initialization with full reflection
            initializeForJvm();
        }
    }
    
    private void initializeForNativeImage() {
        // Use pre-registered beans and avoid reflection
        usePrecompiledConfiguration();
    }
    
    private void initializeForJvm() {
        // Use standard Spring reflection-based initialization
        useReflectionBasedConfiguration();
    }
}

// Conditional bean creation
@Configuration
public class ConditionalConfiguration {
    
    @Bean
    @ConditionalOnExpression("!T(org.springframework.core.NativeDetector).inNativeImage()")
    public ReflectionBasedService reflectionService() {
        return new ReflectionBasedService();
    }
    
    @Bean
    @ConditionalOnExpression("T(org.springframework.core.NativeDetector).inNativeImage()")
    public PrecompiledService precompiledService() {
        return new PrecompiledService();
    }
}

Best Practices for AOT Optimization

Comprehensive Hints Registration

@Component
public class ComprehensiveHintsRegistrar implements RuntimeHintsRegistrar {
    
    @Override
    public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
        registerReflectionHints(hints);
        registerResourceHints(hints);
        registerSerializationHints(hints);
        registerProxyHints(hints);
    }
    
    private void registerReflectionHints(RuntimeHints hints) {
        // Entity classes need field access for JPA/serialization
        hints.reflection()
             .registerType(User.class, 
                 MemberCategory.DECLARED_FIELDS,
                 MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS)
             .registerType(Order.class,
                 MemberCategory.DECLARED_FIELDS,
                 MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS);
        
        // Service classes need method invocation
        hints.reflection()
             .registerType(UserService.class, MemberCategory.INVOKE_PUBLIC_METHODS)
             .registerType(OrderService.class, MemberCategory.INVOKE_PUBLIC_METHODS);
        
        // Controllers need full reflection access
        hints.reflection()
             .registerType(UserController.class,
                 MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS,
                 MemberCategory.INVOKE_PUBLIC_METHODS,
                 MemberCategory.DECLARED_FIELDS);
    }
    
    private void registerResourceHints(RuntimeHints hints) {
        // Application configuration
        hints.resources()
             .registerPattern("application*.properties")
             .registerPattern("application*.yml")
             .registerPattern("bootstrap*.properties");
        
        // Web resources
        hints.resources()
             .registerPattern("static/**")
             .registerPattern("templates/**")
             .registerPattern("public/**");
        
        // Message bundles
        hints.resources()
             .registerResourceBundle("messages")
             .registerResourceBundle("ValidationMessages");
    }
    
    private void registerSerializationHints(RuntimeHints hints) {
        // DTOs for JSON serialization
        hints.serialization()
             .registerType(UserDto.class)
             .registerType(OrderDto.class)
             .registerType(ApiResponse.class);
        
        // Collection types commonly used in serialization
        hints.serialization()
             .registerType(ArrayList.class)
             .registerType(HashMap.class)
             .registerType(LinkedHashMap.class);
    }
    
    private void registerProxyHints(RuntimeHints hints) {
        // Service interfaces for AOP proxying
        hints.proxies()
             .registerJdkProxy(UserService.class)
             .registerJdkProxy(OrderService.class);
        
        // Transaction and caching proxies
        hints.proxies()
             .registerJdkProxy(
                 TypeReference.of("org.springframework.transaction.interceptor.TransactionalProxy"),
                 TypeReference.of("org.springframework.aop.SpringProxy"));
    }
}

This comprehensive AOT optimization system enables Spring applications to be compiled to efficient native images while maintaining the framework's powerful features and developer experience.

Install with Tessl CLI

npx tessl i tessl/maven-org-springframework--spring-core

docs

annotation-processing.md

aot-optimization.md

core-infrastructure.md

environment-config.md

index.md

resource-management.md

task-execution.md

type-conversion.md

utilities.md

tile.json