Browse Source

Polishing

pull/29620/head
Juergen Hoeller 3 years ago
parent
commit
d5732fed45
  1. 17
      spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGenerator.java
  2. 18
      spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorFactory.java
  3. 10
      spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanRegistrationCodeFragmentsDecorator.java
  4. 8
      spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanRegistrationsAotProcessor.java
  5. 72
      spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorTests.java
  6. 1
      spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java

17
spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGenerator.java

@ -134,10 +134,12 @@ class BeanDefinitionMethodGenerator { @@ -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 { @@ -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 { @@ -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",

18
spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorFactory.java

@ -87,8 +87,7 @@ class BeanDefinitionMethodGeneratorFactory { @@ -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 { @@ -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 { @@ -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 { @@ -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'",

10
spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanRegistrationCodeFragmentsDecorator.java

@ -64,8 +64,7 @@ public class BeanRegistrationCodeFragmentsDecorator implements BeanRegistrationC @@ -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 @@ -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 @@ -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);

8
spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanRegistrationsAotProcessor.java

@ -22,6 +22,7 @@ import java.util.Map; @@ -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; @@ -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;
}

72
spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorTests.java

@ -88,8 +88,7 @@ class BeanDefinitionMethodGeneratorTests { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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());

1
spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java

@ -319,6 +319,7 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo @@ -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);

Loading…
Cancel
Save