From 20b17f02a29de8f10773d400b92f310fc6aba5a2 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 4 Mar 2022 09:50:27 +0100 Subject: [PATCH] Rename BeanInstantiationContributor to Contribution This commit polishes the contribution model where an AOT contributing bean post processor can return a contribution, rather than a contributor. This makes it easier to return `null` if no contribution can be produced now that it is named this way. See gh-28047 --- .../AutowiredAnnotationBeanPostProcessor.java | 14 ++++----- .../AotContributingBeanPostProcessor.java | 9 ++++-- ...ava => BeanInstantiationContribution.java} | 16 ++++------ .../DefaultBeanInstantiationGenerator.java | 22 +++++++------- ...tionBeanInstantiationContributorTests.java | 30 ++++++++++--------- ...efaultBeanInstantiationGeneratorTests.java | 12 ++++---- 6 files changed, 51 insertions(+), 52 deletions(-) rename spring-beans/src/main/java/org/springframework/beans/factory/generator/{BeanInstantiationContributor.java => BeanInstantiationContribution.java} (70%) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java index b015644776..560d0784b0 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java @@ -57,7 +57,7 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.DependencyDescriptor; import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor; import org.springframework.beans.factory.generator.AotContributingBeanPostProcessor; -import org.springframework.beans.factory.generator.BeanInstantiationContributor; +import org.springframework.beans.factory.generator.BeanInstantiationContribution; import org.springframework.beans.factory.generator.InjectionGenerator; import org.springframework.beans.factory.support.LookupOverride; import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor; @@ -268,12 +268,12 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA } @Override - public BeanInstantiationContributor buildAotContributor(RootBeanDefinition beanDefinition, Class beanType, String beanName) { + public BeanInstantiationContribution contribute(RootBeanDefinition beanDefinition, Class beanType, String beanName) { InjectionMetadata metadata = findInjectionMetadata(beanName, beanType, beanDefinition); Collection injectedElements = metadata.getInjectedElements(); return (!ObjectUtils.isEmpty(injectedElements) - ? new AutowiredAnnotationBeanInstantiationContributor(injectedElements) - : BeanInstantiationContributor.NO_OP); + ? new AutowiredAnnotationBeanInstantiationContribution(injectedElements) + : null); } private InjectionMetadata findInjectionMetadata(String beanName, Class beanType, RootBeanDefinition beanDefinition) { @@ -821,19 +821,19 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA } } - private static final class AutowiredAnnotationBeanInstantiationContributor implements BeanInstantiationContributor { + private static final class AutowiredAnnotationBeanInstantiationContribution implements BeanInstantiationContribution { private final Collection injectedElements; private final InjectionGenerator generator; - AutowiredAnnotationBeanInstantiationContributor(Collection injectedElements) { + AutowiredAnnotationBeanInstantiationContribution(Collection injectedElements) { this.injectedElements = injectedElements; this.generator = new InjectionGenerator(); } @Override - public void contribute(CodeContribution contribution) { + public void applyTo(CodeContribution contribution) { this.injectedElements.forEach(element -> { boolean isRequired = isRequired(element); Member member = element.getMember(); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/generator/AotContributingBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/generator/AotContributingBeanPostProcessor.java index b3197e04d8..c1247d9f3f 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/generator/AotContributingBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/generator/AotContributingBeanPostProcessor.java @@ -18,6 +18,7 @@ package org.springframework.beans.factory.generator; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.lang.Nullable; /** * Specialization of {@link BeanPostProcessor} that contributes to bean @@ -35,12 +36,14 @@ import org.springframework.beans.factory.support.RootBeanDefinition; public interface AotContributingBeanPostProcessor extends BeanPostProcessor { /** - * Build a {@link BeanInstantiationContributor} for the given bean definition. + * Contribute a {@link BeanInstantiationContribution} for the given bean definition, + * if applicable. * @param beanDefinition the merged bean definition for the bean * @param beanType the inferred type of the bean * @param beanName the name of the bean - * @return the contributor to use + * @return the contribution to use or {@code null} if the bean should not be processed */ - BeanInstantiationContributor buildAotContributor(RootBeanDefinition beanDefinition, Class beanType, String beanName); + @Nullable + BeanInstantiationContribution contribute(RootBeanDefinition beanDefinition, Class beanType, String beanName); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanInstantiationContributor.java b/spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanInstantiationContribution.java similarity index 70% rename from spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanInstantiationContributor.java rename to spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanInstantiationContribution.java index 83cd1ec698..b4ba65715c 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanInstantiationContributor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanInstantiationContribution.java @@ -19,24 +19,18 @@ package org.springframework.beans.factory.generator; import org.springframework.aot.generator.CodeContribution; /** - * Contributor to the code that instantiates a bean following ahead of time + * A contribution to the instantiation of a bean following ahead of time * processing. * * @author Stephane Nicoll * @since 6.0 */ @FunctionalInterface -public interface BeanInstantiationContributor { +public interface BeanInstantiationContribution { /** - * A {@link BeanInstantiationContributor} that does not contribute anything - * to the {@link CodeContribution}. - */ - BeanInstantiationContributor NO_OP = contribution -> { }; - - /** - * Contribute to the specified {@link CodeContribution}. - *

Implementation of this interface can assume the following variables + * Contribute bean instantiation to the specified {@link CodeContribution}. + *

Implementations of this interface can assume the following variables * to be accessible: *

    *
  • {@code beanFactory}: the general {@code DefaultListableBeanFactory}
  • @@ -45,6 +39,6 @@ public interface BeanInstantiationContributor { *
* @param contribution the {@link CodeContribution} to use */ - void contribute(CodeContribution contribution); + void applyTo(CodeContribution contribution); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/generator/DefaultBeanInstantiationGenerator.java b/spring-beans/src/main/java/org/springframework/beans/factory/generator/DefaultBeanInstantiationGenerator.java index fe40951b97..147f74a239 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/generator/DefaultBeanInstantiationGenerator.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/generator/DefaultBeanInstantiationGenerator.java @@ -36,25 +36,25 @@ import org.springframework.util.ClassUtils; * Write the necessary statements to instantiate a bean. * * @author Stephane Nicoll - * @see BeanInstantiationContributor + * @see BeanInstantiationContribution */ class DefaultBeanInstantiationGenerator { private final Executable instanceCreator; - private final List contributors; + private final List contributions; private final InjectionGenerator injectionGenerator; private final Options beanInstanceOptions; - DefaultBeanInstantiationGenerator(Executable instanceCreator, List contributors) { + DefaultBeanInstantiationGenerator(Executable instanceCreator, List contributions) { this.instanceCreator = instanceCreator; - this.contributors = List.copyOf(contributors); + this.contributions = List.copyOf(contributions); this.injectionGenerator = new InjectionGenerator(); this.beanInstanceOptions = Options.defaults().useReflection(member -> false) - .assignReturnType(member -> !this.contributors.isEmpty()).build(); + .assignReturnType(member -> !this.contributions.isEmpty()).build(); } /** @@ -78,7 +78,7 @@ class DefaultBeanInstantiationGenerator { private void writeBeanInstantiation(CodeContribution contribution, Constructor constructor) { Class declaringType = ClassUtils.getUserClass(constructor.getDeclaringClass()); boolean innerClass = isInnerClass(declaringType); - boolean multiStatements = !this.contributors.isEmpty(); + boolean multiStatements = !this.contributions.isEmpty(); int minArgs = isInnerClass(declaringType) ? 2 : 1; CodeBlock.Builder code = CodeBlock.builder(); // Shortcut for common case @@ -110,8 +110,8 @@ class DefaultBeanInstantiationGenerator { contribution.statements().addStatement(code.build()); if (multiStatements) { - for (BeanInstantiationContributor contributor : this.contributors) { - contributor.contribute(contribution); + for (BeanInstantiationContribution contributor : this.contributions) { + contributor.applyTo(contribution); } contribution.statements().addStatement("return bean") .add(codeBlock -> codeBlock.unindent().add("}")); @@ -127,7 +127,7 @@ class DefaultBeanInstantiationGenerator { contribution.runtimeHints().reflection().registerMethod(method, hint -> hint.withMode(ExecutableMode.INTROSPECT)); List> parameterTypes = new ArrayList<>(Arrays.asList(method.getParameterTypes())); - boolean multiStatements = !this.contributors.isEmpty(); + boolean multiStatements = !this.contributions.isEmpty(); Class declaringType = method.getDeclaringClass(); CodeBlock.Builder code = CodeBlock.builder(); // Shortcut for common case @@ -148,8 +148,8 @@ class DefaultBeanInstantiationGenerator { code.add(this.injectionGenerator.writeInstantiation(method)); contribution.statements().addStatement(code.build()); if (multiStatements) { - for (BeanInstantiationContributor contributor : this.contributors) { - contributor.contribute(contribution); + for (BeanInstantiationContribution contributor : this.contributions) { + contributor.applyTo(contribution); } contribution.statements().addStatement("return bean") .add(codeBlock -> codeBlock.unindent().add("}")); diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanInstantiationContributorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanInstantiationContributorTests.java index a85b5cdd37..391e8a3321 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanInstantiationContributorTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanInstantiationContributorTests.java @@ -24,11 +24,12 @@ import org.springframework.aot.hint.ExecutableMode; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.TypeReference; import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessorTests.ResourceInjectionBean; -import org.springframework.beans.factory.generator.BeanInstantiationContributor; +import org.springframework.beans.factory.generator.BeanInstantiationContribution; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.testfixture.beans.TestBean; import org.springframework.core.env.Environment; import org.springframework.javapoet.support.CodeSnippet; +import org.springframework.lang.Nullable; import static org.assertj.core.api.Assertions.assertThat; @@ -37,10 +38,10 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Stephane Nicoll */ -class AutowiredAnnotationBeanInstantiationContributorTests { +class AutowiredAnnotationBeanInstantiationContributionTests { @Test - void buildAotContributorWithPackageProtectedFieldInjection() { + void contributeWithPackageProtectedFieldInjection() { CodeContribution contribution = contribute(PackageProtectedFieldInjectionSample.class); assertThat(CodeSnippet.process(contribution.statements().toCodeBlock())).isEqualTo(""" instanceContext.field("environment", Environment.class) @@ -58,12 +59,12 @@ class AutowiredAnnotationBeanInstantiationContributorTests { } @Test - void buildAotContributorWithPrivateFieldInjection() { + void contributeWithPrivateFieldInjection() { CodeContribution contribution = contribute(PrivateFieldInjectionSample.class); assertThat(CodeSnippet.process(contribution.statements().toCodeBlock())).isEqualTo(""" instanceContext.field("environment", Environment.class) .invoke(beanFactory, (attributes) -> { - Field environmentField = ReflectionUtils.findField(AutowiredAnnotationBeanInstantiationContributorTests.PrivateFieldInjectionSample.class, "environment", Environment.class); + Field environmentField = ReflectionUtils.findField(AutowiredAnnotationBeanInstantiationContributionTests.PrivateFieldInjectionSample.class, "environment", Environment.class); ReflectionUtils.makeAccessible(environmentField); ReflectionUtils.setField(environmentField, bean, attributes.get(0)); })"""); @@ -79,7 +80,7 @@ class AutowiredAnnotationBeanInstantiationContributorTests { } @Test - void buildAotContributorWithPublicMethodInjection() { + void contributeWithPublicMethodInjection() { CodeContribution contribution = contribute(PublicMethodInjectionSample.class); assertThat(CodeSnippet.process(contribution.statements().toCodeBlock())).isEqualTo(""" instanceContext.method("setTestBean", TestBean.class) @@ -95,7 +96,7 @@ class AutowiredAnnotationBeanInstantiationContributorTests { } @Test - void buildAotContributorWithInjectionPoints() { + void contributeWithInjectionPoints() { CodeContribution contribution = contribute(ResourceInjectionBean.class); assertThat(CodeSnippet.process(contribution.statements().toCodeBlock())).isEqualTo(""" instanceContext.field("testBean", TestBean.class) @@ -116,23 +117,24 @@ class AutowiredAnnotationBeanInstantiationContributorTests { } @Test - void buildAotContributorWithoutInjectionPoints() { - BeanInstantiationContributor contributor = createAotContributor(String.class); - assertThat(contributor).isNotNull().isSameAs(BeanInstantiationContributor.NO_OP); + void contributeWithoutInjectionPoints() { + BeanInstantiationContribution contributor = createContribution(String.class); + assertThat(contributor).isNull(); } private DefaultCodeContribution contribute(Class type) { - BeanInstantiationContributor contributor = createAotContributor(type); + BeanInstantiationContribution contributor = createContribution(type); assertThat(contributor).isNotNull(); DefaultCodeContribution contribution = new DefaultCodeContribution(new RuntimeHints()); - contributor.contribute(contribution); + contributor.applyTo(contribution); return contribution; } - private BeanInstantiationContributor createAotContributor(Class type) { + @Nullable + private BeanInstantiationContribution createContribution(Class type) { AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor(); RootBeanDefinition beanDefinition = new RootBeanDefinition(type); - return bpp.buildAotContributor(beanDefinition, type, "test"); + return bpp.contribute(beanDefinition, type, "test"); } diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/generator/DefaultBeanInstantiationGeneratorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/generator/DefaultBeanInstantiationGeneratorTests.java index 29f5d49995..11d9481654 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/generator/DefaultBeanInstantiationGeneratorTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/generator/DefaultBeanInstantiationGeneratorTests.java @@ -106,10 +106,10 @@ class DefaultBeanInstantiationGeneratorTests { } @Test - void generateUsingNoArgConstructorAndContributorsDoesNotUseMethodReference() { + void generateUsingNoArgConstructorAndContributionsDoesNotUseMethodReference() { CodeContribution contribution = generate(SimpleConfiguration.class.getDeclaredConstructors()[0], contrib -> contrib.statements().add(CodeBlock.of("// hello\n")), - BeanInstantiationContributor.NO_OP); + contrib -> {}); assertThat(code(contribution)).isEqualTo(""" (instanceContext) -> { SimpleConfiguration bean = new SimpleConfiguration(); @@ -119,7 +119,7 @@ class DefaultBeanInstantiationGeneratorTests { } @Test - void generateUsingContributorsRegisterHints() { + void generateUsingContributionsRegisterHints() { CodeContribution contribution = generate(SimpleConfiguration.class.getDeclaredConstructors()[0], contrib -> { contrib.statements().add(CodeBlock.of("// hello\n")); @@ -170,7 +170,7 @@ class DefaultBeanInstantiationGeneratorTests { } @Test - void generateUsingMethodAndContributors() { + void generateUsingMethodAndContributions() { CodeContribution contribution = generate(method(SimpleConfiguration.class, "stringBean"), contrib -> { contrib.statements().add(CodeBlock.of("// hello\n")); @@ -240,9 +240,9 @@ class DefaultBeanInstantiationGeneratorTests { } private CodeContribution generate(Executable executable, - BeanInstantiationContributor... beanInstantiationContributors) { + BeanInstantiationContribution... beanInstantiationContributions) { DefaultBeanInstantiationGenerator generator = new DefaultBeanInstantiationGenerator(executable, - Arrays.asList(beanInstantiationContributors)); + Arrays.asList(beanInstantiationContributions)); return generator.generateBeanInstantiation(new RuntimeHints()); }