Polishing
This commit is contained in:
@@ -134,10 +134,12 @@ class BeanDefinitionMethodGenerator {
|
||||
type.addJavadoc("Bean definitions for {@link $T}", topLevelClassName);
|
||||
type.addModifiers(Modifier.PUBLIC);
|
||||
});
|
||||
|
||||
List<String> names = target.simpleNames();
|
||||
if (names.size() == 1) {
|
||||
return generatedClass;
|
||||
}
|
||||
|
||||
List<String> namesToProcess = names.subList(1, names.size());
|
||||
ClassName currentTargetClassName = topLevelClassName;
|
||||
GeneratedClass tmp = generatedClass;
|
||||
@@ -148,8 +150,7 @@ class BeanDefinitionMethodGenerator {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
private static GeneratedClass createInnerClass(GeneratedClass generatedClass,
|
||||
String name, ClassName target) {
|
||||
private static GeneratedClass createInnerClass(GeneratedClass generatedClass, String name, ClassName target) {
|
||||
return generatedClass.getOrAdd(name, type -> {
|
||||
type.addJavadoc("Bean definitions for {@link $T}", target);
|
||||
type.addModifiers(Modifier.PUBLIC, Modifier.STATIC);
|
||||
@@ -167,16 +168,16 @@ class BeanDefinitionMethodGenerator {
|
||||
return codeFragments;
|
||||
}
|
||||
|
||||
private GeneratedMethod generateBeanDefinitionMethod(
|
||||
GenerationContext generationContext, ClassName className,
|
||||
GeneratedMethods generatedMethods, BeanRegistrationCodeFragments codeFragments,
|
||||
Modifier modifier) {
|
||||
private GeneratedMethod generateBeanDefinitionMethod(GenerationContext generationContext,
|
||||
ClassName className, GeneratedMethods generatedMethods,
|
||||
BeanRegistrationCodeFragments codeFragments, Modifier modifier) {
|
||||
|
||||
BeanRegistrationCodeGenerator codeGenerator = new BeanRegistrationCodeGenerator(
|
||||
className, generatedMethods, this.registeredBean,
|
||||
this.constructorOrFactoryMethod, codeFragments);
|
||||
this.aotContributions.forEach(aotContribution -> aotContribution
|
||||
.applyTo(generationContext, codeGenerator));
|
||||
|
||||
this.aotContributions.forEach(aotContribution -> aotContribution.applyTo(generationContext, codeGenerator));
|
||||
|
||||
return generatedMethods.add("getBeanDefinition", method -> {
|
||||
method.addJavadoc("Get the $L definition for '$L'",
|
||||
(!this.registeredBean.isInnerBean()) ? "bean" : "inner-bean",
|
||||
|
||||
@@ -87,8 +87,7 @@ class BeanDefinitionMethodGeneratorFactory {
|
||||
* {@link BeanRegistrationAotProcessor} provided contributions.
|
||||
* @param registeredBean the registered bean
|
||||
* @param currentPropertyName the property name that this bean belongs to
|
||||
* @return a new {@link BeanDefinitionMethodGenerator} instance or
|
||||
* {@code null}
|
||||
* @return a new {@link BeanDefinitionMethodGenerator} instance or {@code null}
|
||||
*/
|
||||
@Nullable
|
||||
BeanDefinitionMethodGenerator getBeanDefinitionMethodGenerator(
|
||||
@@ -97,8 +96,7 @@ class BeanDefinitionMethodGeneratorFactory {
|
||||
if (isExcluded(registeredBean)) {
|
||||
return null;
|
||||
}
|
||||
List<BeanRegistrationAotContribution> contributions = getAotContributions(
|
||||
registeredBean);
|
||||
List<BeanRegistrationAotContribution> contributions = getAotContributions(registeredBean);
|
||||
return new BeanDefinitionMethodGenerator(this, registeredBean,
|
||||
currentPropertyName, contributions);
|
||||
}
|
||||
@@ -110,8 +108,7 @@ class BeanDefinitionMethodGeneratorFactory {
|
||||
* {@link BeanDefinitionMethodGenerator} will include all
|
||||
* {@link BeanRegistrationAotProcessor} provided contributions.
|
||||
* @param registeredBean the registered bean
|
||||
* @return a new {@link BeanDefinitionMethodGenerator} instance or
|
||||
* {@code null}
|
||||
* @return a new {@link BeanDefinitionMethodGenerator} instance or {@code null}
|
||||
*/
|
||||
@Nullable
|
||||
BeanDefinitionMethodGenerator getBeanDefinitionMethodGenerator(RegisteredBean registeredBean) {
|
||||
@@ -142,19 +139,16 @@ class BeanDefinitionMethodGeneratorFactory {
|
||||
}
|
||||
if (BeanRegistrationAotProcessor.class.isAssignableFrom(beanClass)) {
|
||||
BeanRegistrationAotProcessor processor = this.aotProcessors.findByBeanName(registeredBean.getBeanName());
|
||||
return (processor == null) || processor.isBeanExcludedFromAotProcessing();
|
||||
return (processor == null || processor.isBeanExcludedFromAotProcessing());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private List<BeanRegistrationAotContribution> getAotContributions(
|
||||
RegisteredBean registeredBean) {
|
||||
|
||||
private List<BeanRegistrationAotContribution> getAotContributions(RegisteredBean registeredBean) {
|
||||
String beanName = registeredBean.getBeanName();
|
||||
List<BeanRegistrationAotContribution> contributions = new ArrayList<>();
|
||||
for (BeanRegistrationAotProcessor aotProcessor : this.aotProcessors) {
|
||||
BeanRegistrationAotContribution contribution = aotProcessor
|
||||
.processAheadOfTime(registeredBean);
|
||||
BeanRegistrationAotContribution contribution = aotProcessor.processAheadOfTime(registeredBean);
|
||||
if (contribution != null) {
|
||||
logger.trace(LogMessage.format(
|
||||
"Adding bean registration AOT contribution %S from %S to '%S'",
|
||||
|
||||
@@ -64,8 +64,7 @@ public class BeanRegistrationCodeFragmentsDecorator implements BeanRegistrationC
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeBlock generateSetBeanDefinitionPropertiesCode(
|
||||
GenerationContext generationContext,
|
||||
public CodeBlock generateSetBeanDefinitionPropertiesCode(GenerationContext generationContext,
|
||||
BeanRegistrationCode beanRegistrationCode, RootBeanDefinition beanDefinition,
|
||||
Predicate<String> attributeFilter) {
|
||||
|
||||
@@ -74,8 +73,7 @@ public class BeanRegistrationCodeFragmentsDecorator implements BeanRegistrationC
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeBlock generateSetBeanInstanceSupplierCode(
|
||||
GenerationContext generationContext,
|
||||
public CodeBlock generateSetBeanInstanceSupplierCode(GenerationContext generationContext,
|
||||
BeanRegistrationCode beanRegistrationCode, CodeBlock instanceSupplierCode,
|
||||
List<MethodReference> postProcessors) {
|
||||
|
||||
@@ -85,8 +83,8 @@ public class BeanRegistrationCodeFragmentsDecorator implements BeanRegistrationC
|
||||
|
||||
@Override
|
||||
public CodeBlock generateInstanceSupplierCode(GenerationContext generationContext,
|
||||
BeanRegistrationCode beanRegistrationCode,
|
||||
Executable constructorOrFactoryMethod, boolean allowDirectSupplierShortcut) {
|
||||
BeanRegistrationCode beanRegistrationCode, Executable constructorOrFactoryMethod,
|
||||
boolean allowDirectSupplierShortcut) {
|
||||
|
||||
return this.delegate.generateInstanceSupplierCode(generationContext,
|
||||
beanRegistrationCode, constructorOrFactoryMethod, allowDirectSupplierShortcut);
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.Map;
|
||||
import org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.Registration;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RegisteredBean;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* {@link BeanFactoryInitializationAotProcessor} that contributes code to
|
||||
@@ -35,19 +36,22 @@ import org.springframework.beans.factory.support.RegisteredBean;
|
||||
class BeanRegistrationsAotProcessor implements BeanFactoryInitializationAotProcessor {
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public BeanRegistrationsAotContribution processAheadOfTime(ConfigurableListableBeanFactory beanFactory) {
|
||||
BeanDefinitionMethodGeneratorFactory beanDefinitionMethodGeneratorFactory =
|
||||
new BeanDefinitionMethodGeneratorFactory(beanFactory);
|
||||
Map<String, Registration> registrations = new LinkedHashMap<>();
|
||||
|
||||
for (String beanName : beanFactory.getBeanDefinitionNames()) {
|
||||
RegisteredBean registeredBean = RegisteredBean.of(beanFactory, beanName);
|
||||
BeanDefinitionMethodGenerator beanDefinitionMethodGenerator = beanDefinitionMethodGeneratorFactory
|
||||
.getBeanDefinitionMethodGenerator(registeredBean);
|
||||
BeanDefinitionMethodGenerator beanDefinitionMethodGenerator =
|
||||
beanDefinitionMethodGeneratorFactory.getBeanDefinitionMethodGenerator(registeredBean);
|
||||
if (beanDefinitionMethodGenerator != null) {
|
||||
registrations.put(beanName, new Registration(beanDefinitionMethodGenerator,
|
||||
beanFactory.getAliases(beanName)));
|
||||
}
|
||||
}
|
||||
|
||||
if (registrations.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -88,8 +88,7 @@ class BeanDefinitionMethodGeneratorTests {
|
||||
|
||||
@Test
|
||||
void generateBeanDefinitionMethodGeneratesMethod() {
|
||||
RegisteredBean registeredBean = registerBean(
|
||||
new RootBeanDefinition(TestBean.class));
|
||||
RegisteredBean registeredBean = registerBean(new RootBeanDefinition(TestBean.class));
|
||||
BeanDefinitionMethodGenerator generator = new BeanDefinitionMethodGenerator(
|
||||
this.methodGeneratorFactory, registeredBean, null,
|
||||
Collections.emptyList());
|
||||
@@ -172,10 +171,8 @@ class BeanDefinitionMethodGeneratorTests {
|
||||
|
||||
@Test
|
||||
void generateBeanDefinitionMethodWhenHasInstancePostProcessorGeneratesMethod() {
|
||||
RegisteredBean registeredBean = registerBean(
|
||||
new RootBeanDefinition(TestBean.class));
|
||||
BeanRegistrationAotContribution aotContribution = (generationContext,
|
||||
beanRegistrationCode) -> {
|
||||
RegisteredBean registeredBean = registerBean(new RootBeanDefinition(TestBean.class));
|
||||
BeanRegistrationAotContribution aotContribution = (generationContext, beanRegistrationCode) -> {
|
||||
GeneratedMethod generatedMethod = beanRegistrationCode.getMethods().add("postProcess", method ->
|
||||
method.addModifiers(Modifier.STATIC)
|
||||
.addParameter(RegisteredBean.class, "registeredBean")
|
||||
@@ -183,16 +180,14 @@ class BeanDefinitionMethodGeneratorTests {
|
||||
.returns(TestBean.class).addCode("return new $T($S);", TestBean.class, "postprocessed"));
|
||||
beanRegistrationCode.addInstancePostProcessor(generatedMethod.toMethodReference());
|
||||
};
|
||||
List<BeanRegistrationAotContribution> aotContributions = Collections
|
||||
.singletonList(aotContribution);
|
||||
List<BeanRegistrationAotContribution> aotContributions = Collections.singletonList(aotContribution);
|
||||
BeanDefinitionMethodGenerator generator = new BeanDefinitionMethodGenerator(
|
||||
this.methodGeneratorFactory, registeredBean, null, aotContributions);
|
||||
MethodReference method = generator.generateBeanDefinitionMethod(
|
||||
this.generationContext, this.beanRegistrationsCode);
|
||||
compile(method, (actual, compiled) -> {
|
||||
assertThat(actual.getBeanClass()).isEqualTo(TestBean.class);
|
||||
InstanceSupplier<?> supplier = (InstanceSupplier<?>) actual
|
||||
.getInstanceSupplier();
|
||||
InstanceSupplier<?> supplier = (InstanceSupplier<?>) actual.getInstanceSupplier();
|
||||
try {
|
||||
TestBean instance = (TestBean) supplier.get(registeredBean);
|
||||
assertThat(instance.getName()).isEqualTo("postprocessed");
|
||||
@@ -204,9 +199,10 @@ class BeanDefinitionMethodGeneratorTests {
|
||||
});
|
||||
}
|
||||
|
||||
@Test // gh-28748
|
||||
@Test // gh-28748
|
||||
void generateBeanDefinitionMethodWhenHasInstancePostProcessorAndFactoryMethodGeneratesMethod() {
|
||||
this.beanFactory.registerBeanDefinition("testBeanConfiguration", new RootBeanDefinition(TestBeanConfiguration.class));
|
||||
this.beanFactory.registerBeanDefinition("testBeanConfiguration",
|
||||
new RootBeanDefinition(TestBeanConfiguration.class));
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(TestBean.class);
|
||||
beanDefinition.setFactoryBeanName("testBeanConfiguration");
|
||||
beanDefinition.setFactoryMethodName("testBean");
|
||||
@@ -220,8 +216,7 @@ class BeanDefinitionMethodGeneratorTests {
|
||||
.returns(TestBean.class).addCode("return new $T($S);", TestBean.class, "postprocessed"));
|
||||
beanRegistrationCode.addInstancePostProcessor(generatedMethod.toMethodReference());
|
||||
};
|
||||
List<BeanRegistrationAotContribution> aotContributions = Collections
|
||||
.singletonList(aotContribution);
|
||||
List<BeanRegistrationAotContribution> aotContributions = Collections.singletonList(aotContribution);
|
||||
BeanDefinitionMethodGenerator generator = new BeanDefinitionMethodGenerator(
|
||||
this.methodGeneratorFactory, registeredBean, null, aotContributions);
|
||||
MethodReference method = generator.generateBeanDefinitionMethod(
|
||||
@@ -244,10 +239,9 @@ class BeanDefinitionMethodGeneratorTests {
|
||||
|
||||
@Test
|
||||
void generateBeanDefinitionMethodWhenHasCodeFragmentsCustomizerGeneratesMethod() {
|
||||
RegisteredBean registeredBean = registerBean(
|
||||
new RootBeanDefinition(TestBean.class));
|
||||
BeanRegistrationAotContribution aotContribution = BeanRegistrationAotContribution
|
||||
.withCustomCodeFragments(this::customizeBeanDefinitionCode);
|
||||
RegisteredBean registeredBean = registerBean(new RootBeanDefinition(TestBean.class));
|
||||
BeanRegistrationAotContribution aotContribution =
|
||||
BeanRegistrationAotContribution.withCustomCodeFragments(this::customizeBeanDefinitionCode);
|
||||
List<BeanRegistrationAotContribution> aotContributions = Collections.singletonList(aotContribution);
|
||||
BeanDefinitionMethodGenerator generator = new BeanDefinitionMethodGenerator(
|
||||
this.methodGeneratorFactory, registeredBean, null, aotContributions);
|
||||
@@ -260,21 +254,16 @@ class BeanDefinitionMethodGeneratorTests {
|
||||
});
|
||||
}
|
||||
|
||||
private BeanRegistrationCodeFragments customizeBeanDefinitionCode(
|
||||
BeanRegistrationCodeFragments codeFragments) {
|
||||
private BeanRegistrationCodeFragments customizeBeanDefinitionCode(BeanRegistrationCodeFragments codeFragments) {
|
||||
return new BeanRegistrationCodeFragmentsDecorator(codeFragments) {
|
||||
|
||||
@Override
|
||||
public CodeBlock generateNewBeanDefinitionCode(
|
||||
GenerationContext generationContext,
|
||||
ResolvableType beanType,
|
||||
BeanRegistrationCode beanRegistrationCode) {
|
||||
public CodeBlock generateNewBeanDefinitionCode(GenerationContext generationContext,
|
||||
ResolvableType beanType, BeanRegistrationCode beanRegistrationCode) {
|
||||
CodeBlock.Builder code = CodeBlock.builder();
|
||||
code.addStatement("// I am custom");
|
||||
code.add(super.generateNewBeanDefinitionCode(generationContext, beanType, beanRegistrationCode));
|
||||
return code.build();
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -301,10 +290,9 @@ class BeanDefinitionMethodGeneratorTests {
|
||||
beanDefinition.setAttribute("a", "A");
|
||||
beanDefinition.setAttribute("b", "B");
|
||||
RegisteredBean registeredBean = registerBean(beanDefinition);
|
||||
BeanRegistrationAotContribution aotContribution = BeanRegistrationAotContribution
|
||||
.withCustomCodeFragments(this::customizeAttributeFilter);
|
||||
List<BeanRegistrationAotContribution> aotContributions = Collections
|
||||
.singletonList(aotContribution);
|
||||
BeanRegistrationAotContribution aotContribution =
|
||||
BeanRegistrationAotContribution.withCustomCodeFragments(this::customizeAttributeFilter);
|
||||
List<BeanRegistrationAotContribution> aotContributions = Collections.singletonList(aotContribution);
|
||||
BeanDefinitionMethodGenerator generator = new BeanDefinitionMethodGenerator(
|
||||
this.methodGeneratorFactory, registeredBean, null,
|
||||
aotContributions);
|
||||
@@ -316,20 +304,15 @@ class BeanDefinitionMethodGeneratorTests {
|
||||
});
|
||||
}
|
||||
|
||||
private BeanRegistrationCodeFragments customizeAttributeFilter(
|
||||
BeanRegistrationCodeFragments codeFragments) {
|
||||
private BeanRegistrationCodeFragments customizeAttributeFilter(BeanRegistrationCodeFragments codeFragments) {
|
||||
return new BeanRegistrationCodeFragmentsDecorator(codeFragments) {
|
||||
|
||||
@Override
|
||||
public CodeBlock generateSetBeanDefinitionPropertiesCode(
|
||||
GenerationContext generationContext,
|
||||
BeanRegistrationCode beanRegistrationCode,
|
||||
RootBeanDefinition beanDefinition,
|
||||
public CodeBlock generateSetBeanDefinitionPropertiesCode(GenerationContext generationContext,
|
||||
BeanRegistrationCode beanRegistrationCode, RootBeanDefinition beanDefinition,
|
||||
Predicate<String> attributeFilter) {
|
||||
return super.generateSetBeanDefinitionPropertiesCode(generationContext,
|
||||
beanRegistrationCode, beanDefinition, "a"::equals);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -471,8 +454,7 @@ class BeanDefinitionMethodGeneratorTests {
|
||||
@Test
|
||||
@CompileWithForkedClassLoader
|
||||
void generateBeanDefinitionMethodWhenPackagePrivateBean() {
|
||||
RegisteredBean registeredBean = registerBean(
|
||||
new RootBeanDefinition(PackagePrivateTestBean.class));
|
||||
RegisteredBean registeredBean = registerBean(new RootBeanDefinition(PackagePrivateTestBean.class));
|
||||
BeanDefinitionMethodGenerator generator = new BeanDefinitionMethodGenerator(
|
||||
this.methodGeneratorFactory, registeredBean, null,
|
||||
Collections.emptyList());
|
||||
@@ -502,6 +484,13 @@ class BeanDefinitionMethodGeneratorTests {
|
||||
testBeanDefinitionMethodInCurrentFile(DocumentBuilderFactory.class, beanDefinition);
|
||||
}
|
||||
|
||||
@Test
|
||||
void generateBeanDefinitionMethodWhenBeanIsOfPrimitiveType() {
|
||||
RootBeanDefinition beanDefinition = (RootBeanDefinition) BeanDefinitionBuilder
|
||||
.rootBeanDefinition(Boolean.class).setFactoryMethod("parseBoolean").addConstructorArgValue("true").getBeanDefinition();
|
||||
testBeanDefinitionMethodInCurrentFile(Boolean.class, beanDefinition);
|
||||
}
|
||||
|
||||
private void testBeanDefinitionMethodInCurrentFile(Class<?> targetType, RootBeanDefinition beanDefinition) {
|
||||
RegisteredBean registeredBean = registerBean(new RootBeanDefinition(beanDefinition));
|
||||
BeanDefinitionMethodGenerator generator = new BeanDefinitionMethodGenerator(
|
||||
@@ -525,8 +514,7 @@ class BeanDefinitionMethodGeneratorTests {
|
||||
return RegisteredBean.of(this.beanFactory, beanName);
|
||||
}
|
||||
|
||||
private void compile(MethodReference method,
|
||||
BiConsumer<RootBeanDefinition, Compiled> result) {
|
||||
private void compile(MethodReference method, BiConsumer<RootBeanDefinition, Compiled> result) {
|
||||
this.beanRegistrationsCode.getTypeBuilder().set(type -> {
|
||||
CodeBlock methodInvocation = method.toInvokeCodeBlock(ArgumentCodeGenerator.none(),
|
||||
this.beanRegistrationsCode.getClassName());
|
||||
|
||||
@@ -319,6 +319,7 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public BeanFactoryInitializationAotContribution processAheadOfTime(ConfigurableListableBeanFactory beanFactory) {
|
||||
boolean hasPropertySourceDescriptors = !CollectionUtils.isEmpty(this.propertySourceDescriptors);
|
||||
boolean hasImportRegistry = beanFactory.containsBean(IMPORT_REGISTRY_BEAN_NAME);
|
||||
|
||||
Reference in New Issue
Block a user