Permit AOT-generated code to run on the JVM as well

This commit updates the codebase so that AOT-generated code can run on
the JVM in an opt-in fashion alongside the existing support of native
images.

When optimizations have been generated, setting the "spring.aot.enabled"
spring property (JVM or spring.properties) allows to opt-in for that
behavior on the JVM.

Closes gh-31244
pull/31267/head
Stephane Nicoll 2 years ago
parent 0dbcb5f6d3
commit fb439b6824

@ -18,11 +18,11 @@ package org.springframework.boot;
import java.util.function.Supplier;
import org.springframework.aot.AotDetector;
import org.springframework.beans.BeanUtils;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.NativeDetector;
import org.springframework.core.io.support.SpringFactoriesLoader;
/**
@ -51,7 +51,7 @@ public interface ApplicationContextFactory {
return context;
}
}
return NativeDetector.inNativeImage() ? new GenericApplicationContext()
return AotDetector.useGeneratedArtifacts() ? new GenericApplicationContext()
: new AnnotationConfigApplicationContext();
}
catch (Exception ex) {

@ -32,6 +32,7 @@ import java.util.stream.Collectors;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aot.AotDetector;
import org.springframework.beans.BeansException;
import org.springframework.beans.CachedIntrospectionResults;
import org.springframework.beans.factory.config.BeanDefinition;
@ -59,10 +60,10 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.aot.ApplicationContextAotInitializer;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.GenericTypeResolver;
import org.springframework.core.NativeDetector;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.annotation.Order;
@ -401,7 +402,7 @@ public class SpringApplication {
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
}
context.addBeanFactoryPostProcessor(new PropertySourceOrderingBeanFactoryPostProcessor(context));
if (!NativeDetector.inNativeImage()) {
if (!AotDetector.useGeneratedArtifacts()) {
// Load the sources
Set<Object> sources = getAllSources();
Assert.notEmpty(sources, "Sources must not be empty");
@ -411,18 +412,13 @@ public class SpringApplication {
}
private void addAotGeneratedInitializerIfNecessary(List<ApplicationContextInitializer<?>> initializers) {
if (NativeDetector.inNativeImage()) {
try {
Class<?> initializerClass = Class.forName(
this.mainApplicationClass.getName() + "__ApplicationContextInitializer", true,
getClassLoader());
ApplicationContextInitializer<?> initializer = (ApplicationContextInitializer<?>) initializerClass
.getDeclaredConstructor().newInstance();
initializers.add(0, initializer);
}
catch (Exception ex) {
throw new IllegalArgumentException("Failed to load AOT-generated ApplicationContextInitializer", ex);
if (AotDetector.useGeneratedArtifacts()) {
String initializerClassName = this.mainApplicationClass.getName() + "__ApplicationContextInitializer";
if (logger.isDebugEnabled()) {
logger.debug("Using AOT generated initializer: " + initializerClassName);
}
initializers.add(0,
(context) -> new ApplicationContextAotInitializer().initialize(context, initializerClassName));
}
}

@ -16,10 +16,10 @@
package org.springframework.boot.web.reactive.context;
import org.springframework.aot.AotDetector;
import org.springframework.boot.ApplicationContextFactory;
import org.springframework.boot.WebApplicationType;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.NativeDetector;
/**
* {@link ApplicationContextFactory} registered in {@code spring.factories} to support
@ -36,7 +36,7 @@ class ReactiveWebServerApplicationContextFactory implements ApplicationContextFa
if (webApplicationType != WebApplicationType.REACTIVE) {
return null;
}
return NativeDetector.inNativeImage() ? new ReactiveWebServerApplicationContext()
return AotDetector.useGeneratedArtifacts() ? new ReactiveWebServerApplicationContext()
: new AnnotationConfigReactiveWebServerApplicationContext();
}

@ -16,10 +16,10 @@
package org.springframework.boot.web.servlet.context;
import org.springframework.aot.AotDetector;
import org.springframework.boot.ApplicationContextFactory;
import org.springframework.boot.WebApplicationType;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.NativeDetector;
/**
* {@link ApplicationContextFactory} registered in {@code spring.factories} to support
@ -36,7 +36,7 @@ class ServletWebServerApplicationContextFactory implements ApplicationContextFac
if (webApplicationType != WebApplicationType.SERVLET) {
return null;
}
return NativeDetector.inNativeImage() ? new ServletWebServerApplicationContext()
return AotDetector.useGeneratedArtifacts() ? new ServletWebServerApplicationContext()
: new AnnotationConfigServletWebServerApplicationContext();
}

Loading…
Cancel
Save