Migrate AOT tests to use GeneratedClasses and refine/polish AOT APIs
Migrate all AOT tests to make use of `GeneratedClasses` rather than directly generating Java files. This commit also refines and polishes AOT APIs to being greater consistency. Specifically: - The `MethodGenerator` interface has been removed in favor of working directly with `GeneratedMethods`. - The visibility of several constructors and methods has been reduced to package-private. - The `using(...)` and `builder` methods have been removed in favor of setting the `Consumer` callbacks directly as constructor arguments. - Variable names for builders are now named `type` or `method` depending on what they're building. Closes gh-28831
This commit is contained in:
@@ -534,10 +534,9 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
|
||||
Map<String, String> mappings = buildImportAwareMappings();
|
||||
if (!mappings.isEmpty()) {
|
||||
GeneratedMethod generatedMethod = beanFactoryInitializationCode
|
||||
.getMethodGenerator()
|
||||
.generateMethod("addImportAwareBeanPostProcessors")
|
||||
.using(builder -> generateAddPostProcessorMethod(builder,
|
||||
mappings));
|
||||
.getMethods()
|
||||
.add("addImportAwareBeanPostProcessors", method ->
|
||||
generateAddPostProcessorMethod(method, mappings));
|
||||
beanFactoryInitializationCode
|
||||
.addInitializer(MethodReference.of(generatedMethod.getName()));
|
||||
ResourceHints hints = generationContext.getRuntimeHints().resources();
|
||||
@@ -546,14 +545,14 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
|
||||
}
|
||||
}
|
||||
|
||||
private void generateAddPostProcessorMethod(MethodSpec.Builder builder,
|
||||
private void generateAddPostProcessorMethod(MethodSpec.Builder method,
|
||||
Map<String, String> mappings) {
|
||||
|
||||
builder.addJavadoc(
|
||||
method.addJavadoc(
|
||||
"Add ImportAwareBeanPostProcessor to support ImportAware beans");
|
||||
builder.addModifiers(Modifier.PRIVATE);
|
||||
builder.addParameter(DefaultListableBeanFactory.class, BEAN_FACTORY_VARIABLE);
|
||||
builder.addCode(generateAddPostProcessorCode(mappings));
|
||||
method.addModifiers(Modifier.PRIVATE);
|
||||
method.addParameter(DefaultListableBeanFactory.class, BEAN_FACTORY_VARIABLE);
|
||||
method.addCode(generateAddPostProcessorCode(mappings));
|
||||
}
|
||||
|
||||
private CodeBlock generateAddPostProcessorCode(Map<String, String> mappings) {
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.context.aot;
|
||||
|
||||
import org.springframework.aot.generate.GeneratedClass;
|
||||
import org.springframework.aot.generate.GenerationContext;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
@@ -47,15 +46,11 @@ public class ApplicationContextAotGenerator {
|
||||
public ClassName generateApplicationContext(GenericApplicationContext applicationContext,
|
||||
GenerationContext generationContext) {
|
||||
applicationContext.refreshForAotProcessing();
|
||||
DefaultListableBeanFactory beanFactory = applicationContext
|
||||
.getDefaultListableBeanFactory();
|
||||
ApplicationContextInitializationCodeGenerator codeGenerator = new ApplicationContextInitializationCodeGenerator();
|
||||
new BeanFactoryInitializationAotContributions(beanFactory).applyTo(generationContext,
|
||||
codeGenerator);
|
||||
GeneratedClass applicationContextInitializer = generationContext.getGeneratedClasses()
|
||||
.forFeature("ApplicationContextInitializer")
|
||||
.generate(codeGenerator.generateJavaFile());
|
||||
return applicationContextInitializer.getName();
|
||||
DefaultListableBeanFactory beanFactory = applicationContext.getDefaultListableBeanFactory();
|
||||
ApplicationContextInitializationCodeGenerator codeGenerator =
|
||||
new ApplicationContextInitializationCodeGenerator(generationContext);
|
||||
new BeanFactoryInitializationAotContributions(beanFactory).applyTo(generationContext, codeGenerator);
|
||||
return codeGenerator.getGeneratedClass().getName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,12 +18,12 @@ package org.springframework.context.aot;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.lang.model.element.Modifier;
|
||||
|
||||
import org.springframework.aot.generate.GeneratedClass;
|
||||
import org.springframework.aot.generate.GeneratedMethods;
|
||||
import org.springframework.aot.generate.MethodGenerator;
|
||||
import org.springframework.aot.generate.GenerationContext;
|
||||
import org.springframework.aot.generate.MethodReference;
|
||||
import org.springframework.beans.factory.aot.BeanFactoryInitializationCode;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
@@ -44,45 +44,41 @@ import org.springframework.javapoet.TypeSpec;
|
||||
class ApplicationContextInitializationCodeGenerator
|
||||
implements BeanFactoryInitializationCode {
|
||||
|
||||
private static final String INITIALIZE_METHOD = "initialize";
|
||||
|
||||
private static final String APPLICATION_CONTEXT_VARIABLE = "applicationContext";
|
||||
|
||||
|
||||
private final GeneratedMethods generatedMethods = new GeneratedMethods();
|
||||
|
||||
private final List<MethodReference> initializers = new ArrayList<>();
|
||||
|
||||
private final GeneratedClass generatedClass;
|
||||
|
||||
@Override
|
||||
public MethodGenerator getMethodGenerator() {
|
||||
return this.generatedMethods;
|
||||
|
||||
ApplicationContextInitializationCodeGenerator(GenerationContext generationContext) {
|
||||
this.generatedClass = generationContext.getGeneratedClasses()
|
||||
.addForFeature("ApplicationContextInitializer", this::generateType);
|
||||
this.generatedClass.reserveMethodNames(INITIALIZE_METHOD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInitializer(MethodReference methodReference) {
|
||||
this.initializers.add(methodReference);
|
||||
|
||||
private void generateType(TypeSpec.Builder type) {
|
||||
type.addJavadoc(
|
||||
"{@link $T} to restore an application context based on previous AOT processing.",
|
||||
ApplicationContextInitializer.class);
|
||||
type.addModifiers(Modifier.PUBLIC);
|
||||
type.addSuperinterface(ParameterizedTypeName.get(
|
||||
ApplicationContextInitializer.class, GenericApplicationContext.class));
|
||||
type.addMethod(generateInitializeMethod());
|
||||
}
|
||||
|
||||
Consumer<TypeSpec.Builder> generateJavaFile() {
|
||||
return builder -> {
|
||||
builder.addJavadoc(
|
||||
"{@link $T} to restore an application context based on previous AOT processing.",
|
||||
ApplicationContextInitializer.class);
|
||||
builder.addModifiers(Modifier.PUBLIC);
|
||||
builder.addSuperinterface(ParameterizedTypeName.get(
|
||||
ApplicationContextInitializer.class, GenericApplicationContext.class));
|
||||
builder.addMethod(generateInitializeMethod());
|
||||
this.generatedMethods.doWithMethodSpecs(builder::addMethod);
|
||||
};
|
||||
}
|
||||
|
||||
private MethodSpec generateInitializeMethod() {
|
||||
MethodSpec.Builder builder = MethodSpec.methodBuilder("initialize");
|
||||
builder.addAnnotation(Override.class);
|
||||
builder.addModifiers(Modifier.PUBLIC);
|
||||
builder.addParameter(GenericApplicationContext.class,
|
||||
MethodSpec.Builder method = MethodSpec.methodBuilder(INITIALIZE_METHOD);
|
||||
method.addAnnotation(Override.class);
|
||||
method.addModifiers(Modifier.PUBLIC);
|
||||
method.addParameter(GenericApplicationContext.class,
|
||||
APPLICATION_CONTEXT_VARIABLE);
|
||||
builder.addCode(generateInitializeCode());
|
||||
return builder.build();
|
||||
method.addCode(generateInitializeCode());
|
||||
return method.build();
|
||||
}
|
||||
|
||||
private CodeBlock generateInitializeCode() {
|
||||
@@ -93,10 +89,23 @@ class ApplicationContextInitializationCodeGenerator
|
||||
builder.addStatement("$L.setAutowireCandidateResolver(new $T())",
|
||||
BEAN_FACTORY_VARIABLE, ContextAnnotationAutowireCandidateResolver.class);
|
||||
for (MethodReference initializer : this.initializers) {
|
||||
builder.addStatement(
|
||||
initializer.toInvokeCodeBlock(CodeBlock.of(BEAN_FACTORY_VARIABLE)));
|
||||
builder.addStatement(initializer.toInvokeCodeBlock(CodeBlock.of(BEAN_FACTORY_VARIABLE)));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
GeneratedClass getGeneratedClass() {
|
||||
return this.generatedClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GeneratedMethods getMethods() {
|
||||
return this.generatedClass.getMethods();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInitializer(MethodReference methodReference) {
|
||||
this.initializers.add(methodReference);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user