Harmonize generated class name conventions
This commit moves the responsibility of naming classes to the GenerationContext. This was already largely the case before, except that the concept of a "mainTarget" and "featureNamePrefix" was specific to bean factory initialization contributors. ClassNameGenerator should now be instantiated with a default target and an optional feature name prefix. As a result, it does no longer generate class names in the "__" package. GeneratedClasses can now provide a new, unique, GeneratedClass or offer a container for retrieving the same GeneratedClass based on an identifier. This lets all contributors use this facility rather than creating JavaFile manually. This also means that ClassNameGenerator is no longer exposed. Because the naming conventions are now part of the GenerationContext, it is required to be able to retrieve a specialized version of it if a code generation round needs to use different naming conventions. A new withName method has been added to that effect. Closes gh-28585
This commit is contained in:
@@ -16,14 +16,14 @@
|
||||
|
||||
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;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.javapoet.ClassName;
|
||||
import org.springframework.javapoet.JavaFile;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Process an {@link ApplicationContext} and its {@link BeanFactory} to generate
|
||||
@@ -42,41 +42,20 @@ public class ApplicationContextAotGenerator {
|
||||
* specified {@link GenerationContext}.
|
||||
* @param applicationContext the application context to handle
|
||||
* @param generationContext the generation context to use
|
||||
* @param generatedInitializerClassName the class name to use for the
|
||||
* generated application context initializer
|
||||
* @return the class name of the {@link ApplicationContextInitializer} entry point
|
||||
*/
|
||||
public void generateApplicationContext(GenericApplicationContext applicationContext,
|
||||
GenerationContext generationContext,
|
||||
ClassName generatedInitializerClassName) {
|
||||
|
||||
generateApplicationContext(applicationContext, null, null, generationContext,
|
||||
generatedInitializerClassName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the specified {@link GenericApplicationContext} and generate the
|
||||
* necessary code to restore the state of its {@link BeanFactory}, using the
|
||||
* specified {@link GenerationContext}.
|
||||
* @param applicationContext the application context to handle
|
||||
* @param target the target class for the generated initializer (used when generating class names)
|
||||
* @param name the name of the application context (used when generating class names)
|
||||
* @param generationContext the generation context to use
|
||||
* @param generatedInitializerClassName the class name to use for the
|
||||
* generated application context initializer
|
||||
*/
|
||||
public void generateApplicationContext(GenericApplicationContext applicationContext,
|
||||
@Nullable Class<?> target, @Nullable String name, GenerationContext generationContext,
|
||||
ClassName generatedInitializerClassName) {
|
||||
|
||||
public ClassName generateApplicationContext(GenericApplicationContext applicationContext,
|
||||
GenerationContext generationContext) {
|
||||
applicationContext.refreshForAotProcessing();
|
||||
DefaultListableBeanFactory beanFactory = applicationContext
|
||||
.getDefaultListableBeanFactory();
|
||||
ApplicationContextInitializationCodeGenerator codeGenerator = new ApplicationContextInitializationCodeGenerator(
|
||||
target, name);
|
||||
ApplicationContextInitializationCodeGenerator codeGenerator = new ApplicationContextInitializationCodeGenerator();
|
||||
new BeanFactoryInitializationAotContributions(beanFactory).applyTo(generationContext,
|
||||
codeGenerator);
|
||||
JavaFile javaFile = codeGenerator.generateJavaFile(generatedInitializerClassName);
|
||||
generationContext.getGeneratedFiles().addSourceFile(javaFile);
|
||||
GeneratedClass applicationContextInitializer = generationContext.getGeneratedClasses()
|
||||
.forFeature("ApplicationContextInitializer")
|
||||
.generate(codeGenerator.generateJavaFile());
|
||||
return applicationContextInitializer.getName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.context.aot;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.lang.model.element.Modifier;
|
||||
|
||||
@@ -29,14 +30,10 @@ import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.javapoet.ClassName;
|
||||
import org.springframework.javapoet.CodeBlock;
|
||||
import org.springframework.javapoet.JavaFile;
|
||||
import org.springframework.javapoet.MethodSpec;
|
||||
import org.springframework.javapoet.ParameterizedTypeName;
|
||||
import org.springframework.javapoet.TypeSpec;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Internal code generator to create the application context initializer.
|
||||
@@ -50,33 +47,11 @@ class ApplicationContextInitializationCodeGenerator
|
||||
private static final String APPLICATION_CONTEXT_VARIABLE = "applicationContext";
|
||||
|
||||
|
||||
@Nullable
|
||||
private final Class<?> target;
|
||||
|
||||
private final String name;
|
||||
|
||||
private final GeneratedMethods generatedMethods = new GeneratedMethods();
|
||||
|
||||
private final List<MethodReference> initializers = new ArrayList<>();
|
||||
|
||||
|
||||
ApplicationContextInitializationCodeGenerator(@Nullable Class<?> target, @Nullable String name) {
|
||||
this.target = target;
|
||||
this.name = (!StringUtils.hasText(name)) ? "" : name;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Class<?> getTarget() {
|
||||
return this.target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodGenerator getMethodGenerator() {
|
||||
return this.generatedMethods;
|
||||
@@ -87,17 +62,17 @@ class ApplicationContextInitializationCodeGenerator
|
||||
this.initializers.add(methodReference);
|
||||
}
|
||||
|
||||
JavaFile generateJavaFile(ClassName className) {
|
||||
TypeSpec.Builder builder = TypeSpec.classBuilder(className);
|
||||
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);
|
||||
return JavaFile.builder(className.packageName(), builder.build()).build();
|
||||
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() {
|
||||
|
||||
Reference in New Issue
Block a user