Allow ApplicationContextAotGenerator to generated better class names

Update `ApplicationContextAotGenerator` so that it can generate class
names based on a `target` class and using the ID of the application
context. Prior to this commit, the generated class name was always
`__.BeanFactoryRegistrations`.

Closes gh-28565
This commit is contained in:
Phillip Webb
2022-06-03 16:43:13 -07:00
parent 243350054b
commit 4bd33cb6e0
9 changed files with 99 additions and 132 deletions

View File

@@ -23,6 +23,7 @@ import org.springframework.context.ApplicationContext;
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
@@ -48,10 +49,29 @@ public class ApplicationContextAotGenerator {
GenerationContext generationContext,
ClassName generatedInitializerClassName) {
generateApplicationContext(applicationContext, 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
* @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, GenerationContext generationContext,
ClassName generatedInitializerClassName) {
applicationContext.refreshForAotProcessing();
DefaultListableBeanFactory beanFactory = applicationContext
.getDefaultListableBeanFactory();
ApplicationContextInitializationCodeGenerator codeGenerator = new ApplicationContextInitializationCodeGenerator();
ApplicationContextInitializationCodeGenerator codeGenerator = new ApplicationContextInitializationCodeGenerator(
target, applicationContext.getId());
new BeanFactoryInitializationAotContributions(beanFactory).applyTo(generationContext,
codeGenerator);
JavaFile javaFile = codeGenerator.generateJavaFile(generatedInitializerClassName);

View File

@@ -35,6 +35,7 @@ import org.springframework.javapoet.JavaFile;
import org.springframework.javapoet.MethodSpec;
import org.springframework.javapoet.ParameterizedTypeName;
import org.springframework.javapoet.TypeSpec;
import org.springframework.util.StringUtils;
/**
* Internal code generator to create the application context initializer.
@@ -48,11 +49,31 @@ class ApplicationContextInitializationCodeGenerator
private static final String APPLICATION_CONTEXT_VARIABLE = "applicationContext";
private final Class<?> target;
private final String id;
private final GeneratedMethods generatedMethods = new GeneratedMethods();
private final List<MethodReference> initializers = new ArrayList<>();
ApplicationContextInitializationCodeGenerator(Class<?> target, String id) {
this.target=target;
this.id = (!StringUtils.hasText(id)) ? "" : id;
}
@Override
public Class<?> getTarget() {
return this.target;
}
@Override
public String getId() {
return this.id;
}
@Override
public MethodGenerator getMethodGenerator() {
return this.generatedMethods;