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
This commit is contained in:
parent
0dbcb5f6d3
commit
fb439b6824
|
@ -18,11 +18,11 @@ package org.springframework.boot;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import org.springframework.aot.AotDetector;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
import org.springframework.context.support.GenericApplicationContext;
|
import org.springframework.context.support.GenericApplicationContext;
|
||||||
import org.springframework.core.NativeDetector;
|
|
||||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,7 +51,7 @@ public interface ApplicationContextFactory {
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NativeDetector.inNativeImage() ? new GenericApplicationContext()
|
return AotDetector.useGeneratedArtifacts() ? new GenericApplicationContext()
|
||||||
: new AnnotationConfigApplicationContext();
|
: new AnnotationConfigApplicationContext();
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
|
|
|
@ -32,6 +32,7 @@ import java.util.stream.Collectors;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import org.springframework.aot.AotDetector;
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.beans.CachedIntrospectionResults;
|
import org.springframework.beans.CachedIntrospectionResults;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
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.AnnotationConfigUtils;
|
||||||
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
|
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
|
||||||
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
|
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
|
||||||
|
import org.springframework.context.aot.ApplicationContextAotInitializer;
|
||||||
import org.springframework.context.support.AbstractApplicationContext;
|
import org.springframework.context.support.AbstractApplicationContext;
|
||||||
import org.springframework.context.support.GenericApplicationContext;
|
import org.springframework.context.support.GenericApplicationContext;
|
||||||
import org.springframework.core.GenericTypeResolver;
|
import org.springframework.core.GenericTypeResolver;
|
||||||
import org.springframework.core.NativeDetector;
|
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
|
@ -401,7 +402,7 @@ public class SpringApplication {
|
||||||
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
|
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
|
||||||
}
|
}
|
||||||
context.addBeanFactoryPostProcessor(new PropertySourceOrderingBeanFactoryPostProcessor(context));
|
context.addBeanFactoryPostProcessor(new PropertySourceOrderingBeanFactoryPostProcessor(context));
|
||||||
if (!NativeDetector.inNativeImage()) {
|
if (!AotDetector.useGeneratedArtifacts()) {
|
||||||
// Load the sources
|
// Load the sources
|
||||||
Set<Object> sources = getAllSources();
|
Set<Object> sources = getAllSources();
|
||||||
Assert.notEmpty(sources, "Sources must not be empty");
|
Assert.notEmpty(sources, "Sources must not be empty");
|
||||||
|
@ -411,18 +412,13 @@ public class SpringApplication {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addAotGeneratedInitializerIfNecessary(List<ApplicationContextInitializer<?>> initializers) {
|
private void addAotGeneratedInitializerIfNecessary(List<ApplicationContextInitializer<?>> initializers) {
|
||||||
if (NativeDetector.inNativeImage()) {
|
if (AotDetector.useGeneratedArtifacts()) {
|
||||||
try {
|
String initializerClassName = this.mainApplicationClass.getName() + "__ApplicationContextInitializer";
|
||||||
Class<?> initializerClass = Class.forName(
|
if (logger.isDebugEnabled()) {
|
||||||
this.mainApplicationClass.getName() + "__ApplicationContextInitializer", true,
|
logger.debug("Using AOT generated initializer: " + initializerClassName);
|
||||||
getClassLoader());
|
|
||||||
ApplicationContextInitializer<?> initializer = (ApplicationContextInitializer<?>) initializerClass
|
|
||||||
.getDeclaredConstructor().newInstance();
|
|
||||||
initializers.add(0, initializer);
|
|
||||||
}
|
|
||||||
catch (Exception ex) {
|
|
||||||
throw new IllegalArgumentException("Failed to load AOT-generated ApplicationContextInitializer", ex);
|
|
||||||
}
|
}
|
||||||
|
initializers.add(0,
|
||||||
|
(context) -> new ApplicationContextAotInitializer().initialize(context, initializerClassName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,10 @@
|
||||||
|
|
||||||
package org.springframework.boot.web.reactive.context;
|
package org.springframework.boot.web.reactive.context;
|
||||||
|
|
||||||
|
import org.springframework.aot.AotDetector;
|
||||||
import org.springframework.boot.ApplicationContextFactory;
|
import org.springframework.boot.ApplicationContextFactory;
|
||||||
import org.springframework.boot.WebApplicationType;
|
import org.springframework.boot.WebApplicationType;
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
import org.springframework.core.NativeDetector;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ApplicationContextFactory} registered in {@code spring.factories} to support
|
* {@link ApplicationContextFactory} registered in {@code spring.factories} to support
|
||||||
|
@ -36,7 +36,7 @@ class ReactiveWebServerApplicationContextFactory implements ApplicationContextFa
|
||||||
if (webApplicationType != WebApplicationType.REACTIVE) {
|
if (webApplicationType != WebApplicationType.REACTIVE) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return NativeDetector.inNativeImage() ? new ReactiveWebServerApplicationContext()
|
return AotDetector.useGeneratedArtifacts() ? new ReactiveWebServerApplicationContext()
|
||||||
: new AnnotationConfigReactiveWebServerApplicationContext();
|
: new AnnotationConfigReactiveWebServerApplicationContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,10 @@
|
||||||
|
|
||||||
package org.springframework.boot.web.servlet.context;
|
package org.springframework.boot.web.servlet.context;
|
||||||
|
|
||||||
|
import org.springframework.aot.AotDetector;
|
||||||
import org.springframework.boot.ApplicationContextFactory;
|
import org.springframework.boot.ApplicationContextFactory;
|
||||||
import org.springframework.boot.WebApplicationType;
|
import org.springframework.boot.WebApplicationType;
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
import org.springframework.core.NativeDetector;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ApplicationContextFactory} registered in {@code spring.factories} to support
|
* {@link ApplicationContextFactory} registered in {@code spring.factories} to support
|
||||||
|
@ -36,7 +36,7 @@ class ServletWebServerApplicationContextFactory implements ApplicationContextFac
|
||||||
if (webApplicationType != WebApplicationType.SERVLET) {
|
if (webApplicationType != WebApplicationType.SERVLET) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return NativeDetector.inNativeImage() ? new ServletWebServerApplicationContext()
|
return AotDetector.useGeneratedArtifacts() ? new ServletWebServerApplicationContext()
|
||||||
: new AnnotationConfigServletWebServerApplicationContext();
|
: new AnnotationConfigServletWebServerApplicationContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue