Adapt to latest API change in Spring Framework

See https://github.com/spring-projects/spring-framework/issues/28585
pull/31520/head
Stephane Nicoll 2 years ago
parent 114b896e3c
commit fe39598e81

@ -30,7 +30,6 @@ import org.springframework.beans.factory.aot.BeanRegistrationCode;
import org.springframework.beans.factory.aot.BeanRegistrationExcludeFilter;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.support.RegisteredBean;
import org.springframework.boot.AotProcessor;
import org.springframework.boot.LazyInitializationBeanFactoryPostProcessor;
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextFactory;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
@ -96,10 +95,9 @@ class ChildManagementContextInitializer implements ApplicationListener<WebServer
BeanFactory parentBeanFactory = ((ConfigurableApplicationContext) this.parentContext).getBeanFactory();
if (registeredBean.getBeanClass().equals(getClass())
&& registeredBean.getBeanFactory().equals(parentBeanFactory)) {
AotProcessor activeAotProcessor = AotProcessor.getActive(this.parentContext);
ConfigurableApplicationContext managementContext = createManagementContext();
registerBeans(managementContext);
return new AotContribution(activeAotProcessor, managementContext);
return new AotContribution(managementContext);
}
return null;
}
@ -155,23 +153,18 @@ class ChildManagementContextInitializer implements ApplicationListener<WebServer
*/
private static class AotContribution implements BeanRegistrationAotContribution {
private final AotProcessor activeAotProcessor;
private final GenericApplicationContext managementContext;
AotContribution(AotProcessor activeAotProcessor, ConfigurableApplicationContext managementContext) {
AotContribution(ConfigurableApplicationContext managementContext) {
Assert.isInstanceOf(GenericApplicationContext.class, managementContext);
this.activeAotProcessor = activeAotProcessor;
this.managementContext = (GenericApplicationContext) managementContext;
}
@Override
public void applyTo(GenerationContext generationContext, BeanRegistrationCode beanRegistrationCode) {
Class<?> target = (this.activeAotProcessor != null) ? this.activeAotProcessor.getApplication() : null;
ClassName generatedInitializerClassName = generationContext.getClassNameGenerator()
.generateClassName(target, "ManagementContextRegistrations");
new ApplicationContextAotGenerator().generateApplicationContext(this.managementContext, target,
"Management", generationContext, generatedInitializerClassName);
GenerationContext managementGenerationContext = generationContext.withName("Management");
ClassName generatedInitializerClassName = new ApplicationContextAotGenerator()
.generateApplicationContext(this.managementContext, managementGenerationContext);
GeneratedMethod postProcessorMethod = beanRegistrationCode.getMethodGenerator()
.generateMethod("addManagementInitializer").using((builder) -> {
builder.addJavadoc("Use AOT management context initialization");

@ -25,13 +25,11 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.aot.generate.ClassNameGenerator;
import org.springframework.aot.generate.DefaultGenerationContext;
import org.springframework.aot.generate.InMemoryGeneratedFiles;
import org.springframework.aot.generate.MethodGenerator;
import org.springframework.aot.generate.MethodReference;
import org.springframework.aot.test.generator.compile.CompileWithTargetClassAccess;
import org.springframework.aot.test.generator.compile.TestCompiler;
import org.springframework.beans.factory.aot.BeanRegistrationCode;
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration;
@ -79,10 +77,10 @@ class ChildManagementContextInitializerAotTests {
EndpointAutoConfiguration.class));
contextRunner.withPropertyValues("server.port=0", "management.server.port=0").prepare((context) -> {
InMemoryGeneratedFiles generatedFiles = new InMemoryGeneratedFiles();
DefaultGenerationContext generationContext = new DefaultGenerationContext(generatedFiles);
ClassName className = ClassName.get("com.example", "TestInitializer");
new ApplicationContextAotGenerator().generateApplicationContext(
(GenericApplicationContext) context.getSourceApplicationContext(), generationContext, className);
DefaultGenerationContext generationContext = new DefaultGenerationContext(
new ClassNameGenerator(TestTarget.class), generatedFiles);
ClassName className = new ApplicationContextAotGenerator().generateApplicationContext(
(GenericApplicationContext) context.getSourceApplicationContext(), generationContext);
generationContext.writeGeneratedContent();
TestCompiler compiler = TestCompiler.forSystem();
compiler.withFiles(generatedFiles).compile((compiled) -> {
@ -105,21 +103,7 @@ class ChildManagementContextInitializerAotTests {
};
}
static class MockBeanRegistrationCode implements BeanRegistrationCode {
@Override
public ClassName getClassName() {
return null;
}
@Override
public MethodGenerator getMethodGenerator() {
return null;
}
@Override
public void addInstancePostProcessor(MethodReference methodReference) {
}
static class TestTarget {
}

@ -25,10 +25,9 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import org.springframework.aot.generate.ClassNameGenerator;
import org.springframework.aot.generate.DefaultGenerationContext;
import org.springframework.aot.generate.FileSystemGeneratedFiles;
import org.springframework.aot.generate.GeneratedFiles.Kind;
@ -62,8 +61,6 @@ public class AotProcessor {
private static final Consumer<ExecutableHint.Builder> INVOKE_CONSTRUCTOR_HINT = (hint) -> hint
.setModes(ExecutableMode.INVOKE);
private static final Map<ApplicationContext, AotProcessor> aotProcessors = new ConcurrentHashMap<>();
private final Class<?> application;
private final String[] applicationArgs;
@ -101,31 +98,17 @@ public class AotProcessor {
this.artifactId = artifactId;
}
/**
* Return the application class being processed.
* @return the application class
*/
public Class<?> getApplication() {
return this.application;
}
/**
* Trigger the processing of the application managed by this instance.
*/
void process() {
public void process() {
deleteExistingOutput();
AotProcessorHook hook = new AotProcessorHook();
SpringApplicationHooks.withHook(hook, this::callApplicationMainMethod);
GenericApplicationContext applicationContext = hook.getApplicationContext();
Assert.notNull(applicationContext, "No application context available after calling main method of '"
+ this.application.getName() + "'. Does it run a SpringApplication?");
aotProcessors.put(applicationContext, this);
try {
performAotProcessing(applicationContext);
}
finally {
aotProcessors.remove(applicationContext);
}
performAotProcessing(applicationContext);
}
private void deleteExistingOutput() {
@ -161,12 +144,11 @@ public class AotProcessor {
private void performAotProcessing(GenericApplicationContext applicationContext) {
FileSystemGeneratedFiles generatedFiles = new FileSystemGeneratedFiles(this::getRoot);
DefaultGenerationContext generationContext = new DefaultGenerationContext(generatedFiles);
DefaultGenerationContext generationContext = new DefaultGenerationContext(
new ClassNameGenerator(this.application), generatedFiles);
ApplicationContextAotGenerator generator = new ApplicationContextAotGenerator();
ClassName generatedInitializerClassName = generationContext.getClassNameGenerator()
.generateClassName(this.application, "ApplicationContextInitializer");
generator.generateApplicationContext(applicationContext, this.application, "", generationContext,
generatedInitializerClassName);
ClassName generatedInitializerClassName = generator.generateApplicationContext(applicationContext,
generationContext);
registerEntryPointHint(generationContext, generatedInitializerClassName);
generationContext.writeGeneratedContent();
writeHints(generationContext.getRuntimeHints());
@ -243,16 +225,6 @@ public class AotProcessor {
.process();
}
/**
* Return the AOT processor that is actively processing the given
* {@link ApplicationContext}.
* @param applicationContext the application context to check
* @return the {@link AotProcessor} or {@code null}
*/
public static AotProcessor getActive(ApplicationContext applicationContext) {
return aotProcessors.get(applicationContext);
}
/**
* Hook used to capture the {@link ApplicationContext} and trigger early exit of main
* method.

@ -25,6 +25,7 @@ import java.util.function.Consumer;
import org.junit.jupiter.api.Test;
import org.springframework.aot.generate.ClassNameGenerator;
import org.springframework.aot.generate.DefaultGenerationContext;
import org.springframework.aot.generate.GenerationContext;
import org.springframework.aot.generate.InMemoryGeneratedFiles;
@ -267,7 +268,8 @@ class ConfigurationPropertiesBeanFactoryInitializationAotProcessorTests {
private RuntimeHints process(ConfigurableListableBeanFactory beanFactory) {
BeanFactoryInitializationAotContribution contribution = this.processor.processAheadOfTime(beanFactory);
assertThat(contribution).isNotNull();
GenerationContext generationContext = new DefaultGenerationContext(new InMemoryGeneratedFiles());
GenerationContext generationContext = new DefaultGenerationContext(new ClassNameGenerator(Object.class),
new InMemoryGeneratedFiles());
contribution.applyTo(generationContext, mock(BeanFactoryInitializationCode.class));
return generationContext.getRuntimeHints();
}

Loading…
Cancel
Save