diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanInstanceSupplier.java b/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanInstanceSupplier.java index 64bfcdab397..a7f1ccfe596 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanInstanceSupplier.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanInstanceSupplier.java @@ -79,21 +79,22 @@ import org.springframework.util.function.ThrowingSupplier; * @author Phillip Webb * @author Stephane Nicoll * @since 6.0 + * @param the type of instance supplied by this supplier * @see AutowiredArguments */ -public final class BeanInstanceSupplier extends AutowiredElementResolver implements InstanceSupplier { +public final class BeanInstanceSupplier extends AutowiredElementResolver implements InstanceSupplier { private final ExecutableLookup lookup; @Nullable - private final ThrowingBiFunction generator; + private final ThrowingBiFunction generator; @Nullable private final String[] shortcuts; private BeanInstanceSupplier(ExecutableLookup lookup, - @Nullable ThrowingBiFunction generator, + @Nullable ThrowingBiFunction generator, @Nullable String[] shortcuts) { this.lookup = lookup; this.generator = generator; @@ -103,28 +104,30 @@ public final class BeanInstanceSupplier extends AutowiredElementResolver impleme /** * Create a {@link BeanInstanceSupplier} that resolves * arguments for the specified bean constructor. + * @param the type of instance supplied * @param parameterTypes the constructor parameter types * @return a new {@link BeanInstanceSupplier} instance */ - public static BeanInstanceSupplier forConstructor( + public static BeanInstanceSupplier forConstructor( Class... parameterTypes) { Assert.notNull(parameterTypes, "'parameterTypes' must not be null"); Assert.noNullElements(parameterTypes, "'parameterTypes' must not contain null elements"); - return new BeanInstanceSupplier( + return new BeanInstanceSupplier<>( new ConstructorLookup(parameterTypes), null, null); } /** * Create a new {@link BeanInstanceSupplier} that * resolves arguments for the specified factory method. + * @param the type of instance supplied * @param declaringClass the class that declares the factory method * @param methodName the factory method name * @param parameterTypes the factory method parameter types * @return a new {@link BeanInstanceSupplier} instance */ - public static BeanInstanceSupplier forFactoryMethod( + public static BeanInstanceSupplier forFactoryMethod( Class declaringClass, String methodName, Class... parameterTypes) { Assert.notNull(declaringClass, "'declaringClass' must not be null"); @@ -132,7 +135,7 @@ public final class BeanInstanceSupplier extends AutowiredElementResolver impleme Assert.notNull(parameterTypes, "'parameterTypes' must not be null"); Assert.noNullElements(parameterTypes, "'parameterTypes' must not contain null elements"); - return new BeanInstanceSupplier( + return new BeanInstanceSupplier<>( new FactoryMethodLookup(declaringClass, methodName, parameterTypes), null, null); } @@ -151,10 +154,10 @@ public final class BeanInstanceSupplier extends AutowiredElementResolver impleme * @return a new {@link BeanInstanceSupplier} instance with the specified * generator */ - public BeanInstanceSupplier withGenerator( - ThrowingBiFunction generator) { + public BeanInstanceSupplier withGenerator( + ThrowingBiFunction generator) { Assert.notNull(generator, "'generator' must not be null"); - return new BeanInstanceSupplier(this.lookup, generator, this.shortcuts); + return new BeanInstanceSupplier(this.lookup, generator, this.shortcuts); } /** @@ -165,10 +168,10 @@ public final class BeanInstanceSupplier extends AutowiredElementResolver impleme * @return a new {@link BeanInstanceSupplier} instance with the specified * generator */ - public BeanInstanceSupplier withGenerator( - ThrowingFunction generator) { + public BeanInstanceSupplier withGenerator( + ThrowingFunction generator) { Assert.notNull(generator, "'generator' must not be null"); - return new BeanInstanceSupplier(this.lookup, (registeredBean, args) -> + return new BeanInstanceSupplier<>(this.lookup, (registeredBean, args) -> generator.apply(registeredBean), this.shortcuts); } @@ -180,9 +183,9 @@ public final class BeanInstanceSupplier extends AutowiredElementResolver impleme * @return a new {@link BeanInstanceSupplier} instance with the specified * generator */ - public BeanInstanceSupplier withGenerator(ThrowingSupplier generator) { + public BeanInstanceSupplier withGenerator(ThrowingSupplier generator) { Assert.notNull(generator, "'generator' must not be null"); - return new BeanInstanceSupplier(this.lookup, (registeredBean, args) -> + return new BeanInstanceSupplier<>(this.lookup, (registeredBean, args) -> generator.get(), this.shortcuts); } @@ -194,22 +197,19 @@ public final class BeanInstanceSupplier extends AutowiredElementResolver impleme * @return a new {@link BeanInstanceSupplier} instance * that uses the shortcuts */ - public BeanInstanceSupplier withShortcuts(String... beanNames) { - return new BeanInstanceSupplier(this.lookup, this.generator, beanNames); + public BeanInstanceSupplier withShortcuts(String... beanNames) { + return new BeanInstanceSupplier(this.lookup, this.generator, beanNames); } @Override - public Object get(RegisteredBean registeredBean) throws Exception { + public T get(RegisteredBean registeredBean) throws Exception { Assert.notNull(registeredBean, "'registeredBean' must not be null"); Executable executable = this.lookup.get(registeredBean); AutowiredArguments arguments = resolveArguments(registeredBean, executable); if (this.generator != null) { return this.generator.apply(registeredBean, arguments); } - else { - return instantiate(registeredBean.getBeanFactory(), executable, - arguments.toArray()); - } + return instantiate(registeredBean.getBeanFactory(), executable, arguments.toArray()); } @Nullable @@ -351,15 +351,16 @@ public final class BeanInstanceSupplier extends AutowiredElementResolver impleme } } - private Object instantiate(ConfigurableBeanFactory beanFactory, Executable executable, + @SuppressWarnings("unchecked") + private T instantiate(ConfigurableBeanFactory beanFactory, Executable executable, Object[] arguments) { try { if (executable instanceof Constructor constructor) { - return instantiate(constructor, arguments); + return (T) instantiate(constructor, arguments); } if (executable instanceof Method method) { - return instantiate(beanFactory, method, arguments); + return (T) instantiate(beanFactory, method, arguments); } } catch (Exception ex) { diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanRegistrationsAotContribution.java b/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanRegistrationsAotContribution.java index 4902ce8a150..2dad04b877f 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanRegistrationsAotContribution.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanRegistrationsAotContribution.java @@ -41,10 +41,8 @@ import org.springframework.javapoet.MethodSpec; class BeanRegistrationsAotContribution implements BeanFactoryInitializationAotContribution { - private static final String BEAN_FACTORY_PARAMETER_NAME = "beanFactory"; - private final Map registrations; diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGenerator.java b/spring-beans/src/main/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGenerator.java index d54644ac1ad..f8acaec900e 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGenerator.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGenerator.java @@ -37,6 +37,7 @@ import org.springframework.javapoet.ClassName; import org.springframework.javapoet.CodeBlock; import org.springframework.javapoet.CodeBlock.Builder; import org.springframework.javapoet.MethodSpec; +import org.springframework.javapoet.ParameterizedTypeName; import org.springframework.util.ClassUtils; import org.springframework.util.function.ThrowingSupplier; @@ -108,7 +109,8 @@ class InstanceSupplierCodeGenerator { private CodeBlock generateCodeForConstructor(RegisteredBean registeredBean, Constructor constructor) { - String name = registeredBean.getBeanName(); + String beanName = registeredBean.getBeanName(); + Class beanClass = registeredBean.getBeanClass(); Class declaringClass = ClassUtils .getUserClass(constructor.getDeclaringClass()); boolean dependsOnBean = ClassUtils.isInnerClass(declaringClass); @@ -116,13 +118,13 @@ class InstanceSupplierCodeGenerator { constructor); if (accessVisibility == AccessVisibility.PUBLIC || accessVisibility == AccessVisibility.PACKAGE_PRIVATE) { - return generateCodeForAccessibleConstructor(name, constructor, dependsOnBean, - declaringClass); + return generateCodeForAccessibleConstructor(beanName, beanClass, constructor, + dependsOnBean, declaringClass); } - return generateCodeForInaccessibleConstructor(name, constructor, dependsOnBean); + return generateCodeForInaccessibleConstructor(beanName, beanClass, constructor, dependsOnBean); } - private CodeBlock generateCodeForAccessibleConstructor(String name, + private CodeBlock generateCodeForAccessibleConstructor(String beanName, Class beanClass, Constructor constructor, boolean dependsOnBean, Class declaringClass) { this.generationContext.getRuntimeHints().reflection() @@ -139,37 +141,36 @@ class InstanceSupplierCodeGenerator { declaringClass); } GeneratedMethod generatedMethod = generateGetInstanceSupplierMethod(method -> - buildGetInstanceMethodForConstructor(method, name, constructor, + buildGetInstanceMethodForConstructor(method, beanName, beanClass, constructor, declaringClass, dependsOnBean, PRIVATE_STATIC)); return generateReturnStatement(generatedMethod); } - private CodeBlock generateCodeForInaccessibleConstructor(String name, - Constructor constructor, boolean dependsOnBean) { + private CodeBlock generateCodeForInaccessibleConstructor(String beanName, + Class beanClass, Constructor constructor, boolean dependsOnBean) { this.generationContext.getRuntimeHints().reflection() .registerConstructor(constructor); GeneratedMethod generatedMethod = generateGetInstanceSupplierMethod(method -> { - method.addJavadoc("Get the bean instance supplier for '$L'.", name); + method.addJavadoc("Get the bean instance supplier for '$L'.", beanName); method.addModifiers(PRIVATE_STATIC); - method.returns(BeanInstanceSupplier.class); + method.returns(ParameterizedTypeName.get(BeanInstanceSupplier.class, beanClass)); int parameterOffset = (!dependsOnBean) ? 0 : 1; - method.addStatement( - generateResolverForConstructor(constructor, parameterOffset)); + method.addStatement(generateResolverForConstructor(beanClass, constructor, parameterOffset)); }); return generateReturnStatement(generatedMethod); } private void buildGetInstanceMethodForConstructor(MethodSpec.Builder method, - String name, Constructor constructor, Class declaringClass, + String beanName, Class beanClass, Constructor constructor, Class declaringClass, boolean dependsOnBean, javax.lang.model.element.Modifier... modifiers) { - method.addJavadoc("Get the bean instance supplier for '$L'.", name); + method.addJavadoc("Get the bean instance supplier for '$L'.", beanName); method.addModifiers(modifiers); - method.returns(BeanInstanceSupplier.class); + method.returns(ParameterizedTypeName.get(BeanInstanceSupplier.class, beanClass)); int parameterOffset = (!dependsOnBean) ? 0 : 1; CodeBlock.Builder code = CodeBlock.builder(); - code.add(generateResolverForConstructor(constructor, parameterOffset)); + code.add(generateResolverForConstructor(beanClass, constructor, parameterOffset)); boolean hasArguments = constructor.getParameterCount() > 0; CodeBlock arguments = hasArguments ? new AutowiredArgumentsCodeGenerator(declaringClass, constructor) @@ -181,13 +182,13 @@ class InstanceSupplierCodeGenerator { method.addStatement(code.build()); } - private CodeBlock generateResolverForConstructor(Constructor constructor, - int parameterOffset) { + private CodeBlock generateResolverForConstructor(Class beanClass, + Constructor constructor, int parameterOffset) { CodeBlock parameterTypes = generateParameterTypesCode( constructor.getParameterTypes(), parameterOffset); - return CodeBlock.of("return $T.forConstructor($L)", - BeanInstanceSupplier.class, parameterTypes); + return CodeBlock.of("return $T.<$T>forConstructor($L)", + BeanInstanceSupplier.class, beanClass, parameterTypes); } private CodeBlock generateNewInstanceCodeForConstructor(boolean dependsOnBean, @@ -204,7 +205,8 @@ class InstanceSupplierCodeGenerator { private CodeBlock generateCodeForFactoryMethod(RegisteredBean registeredBean, Method factoryMethod) { - String name = registeredBean.getBeanName(); + String beanName = registeredBean.getBeanName(); + Class beanClass = registeredBean.getBeanClass(); Class declaringClass = ClassUtils .getUserClass(factoryMethod.getDeclaringClass()); boolean dependsOnBean = !Modifier.isStatic(factoryMethod.getModifiers()); @@ -212,55 +214,56 @@ class InstanceSupplierCodeGenerator { factoryMethod); if (accessVisibility == AccessVisibility.PUBLIC || accessVisibility == AccessVisibility.PACKAGE_PRIVATE) { - return generateCodeForAccessibleFactoryMethod(name, factoryMethod, + return generateCodeForAccessibleFactoryMethod(beanName, beanClass, factoryMethod, declaringClass, dependsOnBean); } - return generateCodeForInaccessibleFactoryMethod(name, factoryMethod, + return generateCodeForInaccessibleFactoryMethod(beanName, beanClass, factoryMethod, declaringClass); } - private CodeBlock generateCodeForAccessibleFactoryMethod(String name, - Method factoryMethod, Class declaringClass, boolean dependsOnBean) { + private CodeBlock generateCodeForAccessibleFactoryMethod(String beanName, + Class beanClass, Method factoryMethod, Class declaringClass, boolean dependsOnBean) { + this.generationContext.getRuntimeHints().reflection() .registerMethod(factoryMethod, INTROSPECT); if (!dependsOnBean && factoryMethod.getParameterCount() == 0) { CodeBlock.Builder code = CodeBlock.builder(); - code.add("$T.forFactoryMethod($T.class, $S)", BeanInstanceSupplier.class, - declaringClass, factoryMethod.getName()); + code.add("$T.<$T>forFactoryMethod($T.class, $S)", BeanInstanceSupplier.class, + beanClass, declaringClass, factoryMethod.getName()); code.add(".withGenerator($T::$L)", declaringClass, factoryMethod.getName()); return code.build(); } GeneratedMethod getInstanceMethod = generateGetInstanceSupplierMethod(method -> - buildGetInstanceMethodForFactoryMethod(method, name, factoryMethod, + buildGetInstanceMethodForFactoryMethod(method, beanName, beanClass, factoryMethod, declaringClass, dependsOnBean, PRIVATE_STATIC)); return generateReturnStatement(getInstanceMethod); } - private CodeBlock generateCodeForInaccessibleFactoryMethod(String name, + private CodeBlock generateCodeForInaccessibleFactoryMethod(String beanName, Class beanClass, Method factoryMethod, Class declaringClass) { this.generationContext.getRuntimeHints().reflection() .registerMethod(factoryMethod); GeneratedMethod getInstanceMethod = generateGetInstanceSupplierMethod(method -> { - method.addJavadoc("Get the bean instance supplier for '$L'.", name); + method.addJavadoc("Get the bean instance supplier for '$L'.", beanName); method.addModifiers(PRIVATE_STATIC); - method.returns(BeanInstanceSupplier.class); - method.addStatement(generateInstanceSupplierForFactoryMethod(factoryMethod, + method.returns(ParameterizedTypeName.get(BeanInstanceSupplier.class, beanClass)); + method.addStatement(generateInstanceSupplierForFactoryMethod(beanClass, factoryMethod, declaringClass, factoryMethod.getName())); }); return generateReturnStatement(getInstanceMethod); } private void buildGetInstanceMethodForFactoryMethod(MethodSpec.Builder method, - String name, Method factoryMethod, Class declaringClass, + String beanName, Class beanClass, Method factoryMethod, Class declaringClass, boolean dependsOnBean, javax.lang.model.element.Modifier... modifiers) { String factoryMethodName = factoryMethod.getName(); - method.addJavadoc("Get the bean instance supplier for '$L'.", name); + method.addJavadoc("Get the bean instance supplier for '$L'.", beanName); method.addModifiers(modifiers); - method.returns(BeanInstanceSupplier.class); + method.returns(ParameterizedTypeName.get(BeanInstanceSupplier.class, beanClass)); CodeBlock.Builder code = CodeBlock.builder(); - code.add(generateInstanceSupplierForFactoryMethod(factoryMethod, declaringClass, factoryMethodName)); + code.add(generateInstanceSupplierForFactoryMethod(beanClass, factoryMethod, declaringClass, factoryMethodName)); boolean hasArguments = factoryMethod.getParameterCount() > 0; CodeBlock arguments = hasArguments ? new AutowiredArgumentsCodeGenerator(declaringClass, factoryMethod) @@ -272,18 +275,18 @@ class InstanceSupplierCodeGenerator { method.addStatement(code.build()); } - private CodeBlock generateInstanceSupplierForFactoryMethod(Method factoryMethod, - Class declaringClass, String factoryMethodName) { + private CodeBlock generateInstanceSupplierForFactoryMethod(Class beanClass, + Method factoryMethod, Class declaringClass, String factoryMethodName) { if (factoryMethod.getParameterCount() == 0) { - return CodeBlock.of("return $T.forFactoryMethod($T.class, $S)", - BeanInstanceSupplier.class, declaringClass, + return CodeBlock.of("return $T.<$T>forFactoryMethod($T.class, $S)", + BeanInstanceSupplier.class, beanClass, declaringClass, factoryMethodName); } CodeBlock parameterTypes = generateParameterTypesCode( factoryMethod.getParameterTypes(), 0); - return CodeBlock.of("return $T.forFactoryMethod($T.class, $S, $L)", - BeanInstanceSupplier.class, declaringClass, + return CodeBlock.of("return $T.<$T>forFactoryMethod($T.class, $S, $L)", + BeanInstanceSupplier.class, beanClass, declaringClass, factoryMethodName, parameterTypes); } diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorTests.java index 49718c0e575..4b4ac5c76fa 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorTests.java @@ -158,6 +158,45 @@ class BeanDefinitionMethodGeneratorTests { }); } + @Test // gh-28748 + void generateBeanDefinitionMethodWhenHasInstancePostProcessorAndFactoryMethodGeneratesMethod() { + this.beanFactory.registerBeanDefinition("testBeanConfiguration", new RootBeanDefinition(TestBeanConfiguration.class)); + RootBeanDefinition beanDefinition = new RootBeanDefinition(TestBean.class); + beanDefinition.setFactoryBeanName("testBeanConfiguration"); + beanDefinition.setFactoryMethodName("testBean"); + RegisteredBean registeredBean = registerBean(beanDefinition); + BeanRegistrationAotContribution aotContribution = (generationContext, + beanRegistrationCode) -> { + GeneratedMethod generatedMethod = beanRegistrationCode.getMethods().add("postProcess", method -> + method.addModifiers(Modifier.STATIC) + .addParameter(RegisteredBean.class, "registeredBean") + .addParameter(TestBean.class, "testBean") + .returns(TestBean.class).addCode("return new $T($S);", TestBean.class, "postprocessed")); + beanRegistrationCode.addInstancePostProcessor(MethodReference.ofStatic( + beanRegistrationCode.getClassName(), generatedMethod.getName())); + }; + List 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(compiled.getSourceFile(".*BeanDefinitions")).contains("BeanInstanceSupplier"); + assertThat(actual.getBeanClass()).isEqualTo(TestBean.class); + InstanceSupplier supplier = (InstanceSupplier) actual + .getInstanceSupplier(); + try { + TestBean instance = (TestBean) supplier.get(registeredBean); + assertThat(instance.getName()).isEqualTo("postprocessed"); + } + catch (Exception ex) { + } + SourceFile sourceFile = compiled.getSourceFile(".*BeanDefinitions"); + assertThat(sourceFile).contains("instanceSupplier.andThen("); + }); + } + @Test void generateBeanDefinitionMethodWhenHasCodeFragmentsCustomizerGeneratesMethod() { RegisteredBean registeredBean = registerBean( @@ -373,7 +412,7 @@ class BeanDefinitionMethodGeneratorTests { .addCode("return $L;", method.toInvokeCodeBlock()).build()); }); this.generationContext.writeGeneratedContent(); - TestCompiler.forSystem().withFiles(this.generatedFiles).compile(compiled -> + TestCompiler.forSystem().withFiles(this.generatedFiles).printFiles(System.out).compile(compiled -> result.accept((RootBeanDefinition) compiled.getInstance(Supplier.class).get(), compiled)); } diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanInstanceSupplierTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanInstanceSupplierTests.java index fa3ae93ca6f..85553b92cd8 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanInstanceSupplierTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanInstanceSupplierTests.java @@ -94,7 +94,7 @@ class BeanInstanceSupplierTests { @Test void forConstructorWhenNotFoundThrowsException() { - BeanInstanceSupplier resolver = BeanInstanceSupplier + BeanInstanceSupplier resolver = BeanInstanceSupplier .forConstructor(InputStream.class); Source source = new Source(SingleArgConstructor.class, resolver); RegisteredBean registerBean = source.registerBean(this.beanFactory); @@ -106,7 +106,7 @@ class BeanInstanceSupplierTests { @Test void forConstructorReturnsNullFactoryMethod() { - BeanInstanceSupplier resolver = BeanInstanceSupplier.forConstructor(String.class); + BeanInstanceSupplier resolver = BeanInstanceSupplier.forConstructor(String.class); assertThat(resolver.getFactoryMethod()).isNull(); } @@ -146,7 +146,7 @@ class BeanInstanceSupplierTests { @Test void forFactoryMethodWhenNotFoundThrowsException() { - BeanInstanceSupplier resolver = BeanInstanceSupplier + BeanInstanceSupplier resolver = BeanInstanceSupplier .forFactoryMethod(SingleArgFactory.class, "single", InputStream.class); Source source = new Source(String.class, resolver); RegisteredBean registerBean = source.registerBean(this.beanFactory); @@ -158,7 +158,7 @@ class BeanInstanceSupplierTests { @Test void forFactoryMethodReturnsFactoryMethod() { - BeanInstanceSupplier resolver = BeanInstanceSupplier + BeanInstanceSupplier resolver = BeanInstanceSupplier .forFactoryMethod(SingleArgFactory.class, "single", String.class); Method factoryMethod = ReflectionUtils.findMethod(SingleArgFactory.class, "single", String.class); assertThat(factoryMethod).isNotNull(); @@ -167,7 +167,7 @@ class BeanInstanceSupplierTests { @Test void withGeneratorWhenBiFunctionIsNullThrowsException() { - BeanInstanceSupplier resolver = BeanInstanceSupplier + BeanInstanceSupplier resolver = BeanInstanceSupplier .forConstructor(); assertThatIllegalArgumentException() .isThrownBy(() -> resolver.withGenerator( @@ -177,7 +177,7 @@ class BeanInstanceSupplierTests { @Test void withGeneratorWhenFunctionIsNullThrowsException() { - BeanInstanceSupplier resolver = BeanInstanceSupplier + BeanInstanceSupplier resolver = BeanInstanceSupplier .forConstructor(); assertThatIllegalArgumentException() .isThrownBy(() -> resolver.withGenerator( @@ -187,7 +187,7 @@ class BeanInstanceSupplierTests { @Test void withGeneratorWhenSupplierIsNullThrowsException() { - BeanInstanceSupplier resolver = BeanInstanceSupplier + BeanInstanceSupplier resolver = BeanInstanceSupplier .forConstructor(); assertThatIllegalArgumentException() .isThrownBy(() -> resolver.withGenerator( @@ -197,7 +197,7 @@ class BeanInstanceSupplierTests { @Test void getWithConstructorDoesNotSetResolvedFactoryMethod() throws Exception { - BeanInstanceSupplier resolver = BeanInstanceSupplier + BeanInstanceSupplier resolver = BeanInstanceSupplier .forConstructor(String.class); this.beanFactory.registerSingleton("one", "1"); Source source = new Source(SingleArgConstructor.class, resolver); @@ -211,7 +211,7 @@ class BeanInstanceSupplierTests { void getWithFactoryMethodSetsResolvedFactoryMethod() { Method factoryMethod = ReflectionUtils.findMethod(SingleArgFactory.class, "single", String.class); assertThat(factoryMethod).isNotNull(); - BeanInstanceSupplier resolver = BeanInstanceSupplier + BeanInstanceSupplier resolver = BeanInstanceSupplier .forFactoryMethod(SingleArgFactory.class, "single", String.class); RootBeanDefinition beanDefinition = new RootBeanDefinition(String.class); assertThat(beanDefinition.getResolvedFactoryMethod()).isNull(); @@ -225,7 +225,7 @@ class BeanInstanceSupplierTests { this.beanFactory.registerSingleton("one", "1"); RegisteredBean registerBean = registrar.registerBean(this.beanFactory); List result = new ArrayList<>(); - BeanInstanceSupplier resolver = BeanInstanceSupplier + BeanInstanceSupplier resolver = BeanInstanceSupplier .forConstructor(String.class) .withGenerator((registeredBean, args) -> result.add(args)); resolver.get(registerBean); @@ -238,8 +238,8 @@ class BeanInstanceSupplierTests { BeanRegistrar registrar = new BeanRegistrar(SingleArgConstructor.class); this.beanFactory.registerSingleton("one", "1"); RegisteredBean registerBean = registrar.registerBean(this.beanFactory); - BeanInstanceSupplier resolver = BeanInstanceSupplier - .forConstructor(String.class) + BeanInstanceSupplier resolver = BeanInstanceSupplier + .forConstructor(String.class) .withGenerator(registeredBean -> "1"); assertThat(resolver.get(registerBean)).isInstanceOf(String.class).isEqualTo("1"); } @@ -249,15 +249,15 @@ class BeanInstanceSupplierTests { BeanRegistrar registrar = new BeanRegistrar(SingleArgConstructor.class); this.beanFactory.registerSingleton("one", "1"); RegisteredBean registerBean = registrar.registerBean(this.beanFactory); - BeanInstanceSupplier resolver = BeanInstanceSupplier - .forConstructor(String.class) + BeanInstanceSupplier resolver = BeanInstanceSupplier + .forConstructor(String.class) .withGenerator(() -> "1"); assertThat(resolver.get(registerBean)).isInstanceOf(String.class).isEqualTo("1"); } @Test void getWhenRegisteredBeanIsNullThrowsException() { - BeanInstanceSupplier resolver = BeanInstanceSupplier + BeanInstanceSupplier resolver = BeanInstanceSupplier .forConstructor(String.class); assertThatIllegalArgumentException().isThrownBy(() -> resolver.get((RegisteredBean) null)) .withMessage("'registeredBean' must not be null"); @@ -548,7 +548,7 @@ class BeanInstanceSupplierTests { } }; - BeanInstanceSupplier resolver = BeanInstanceSupplier + BeanInstanceSupplier resolver = BeanInstanceSupplier .forConstructor(String.class); Source source = new Source(String.class, resolver); beanFactory.registerSingleton("one", "1"); @@ -561,7 +561,7 @@ class BeanInstanceSupplierTests { @Test void resolveArgumentsRegistersDependantBeans() { - BeanInstanceSupplier resolver = BeanInstanceSupplier + BeanInstanceSupplier resolver = BeanInstanceSupplier .forConstructor(String.class); Source source = new Source(SingleArgConstructor.class, resolver); this.beanFactory.registerSingleton("one", "1"); @@ -724,7 +724,7 @@ class BeanInstanceSupplierTests { protected abstract void setup(); protected final void add(Class beanClass, - BeanInstanceSupplier resolver) { + BeanInstanceSupplier resolver) { this.arguments.add(Arguments.of(new Source(beanClass, resolver))); } @@ -762,15 +762,15 @@ class BeanInstanceSupplierTests { static class Source extends BeanRegistrar { - private final BeanInstanceSupplier resolver; + private final BeanInstanceSupplier resolver; public Source(Class beanClass, - BeanInstanceSupplier resolver) { + BeanInstanceSupplier resolver) { super(beanClass); this.resolver = resolver; } - BeanInstanceSupplier getResolver() { + BeanInstanceSupplier getResolver() { return this.resolver; } diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGeneratorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGeneratorTests.java index c1a486f2f6a..295d997815e 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGeneratorTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGeneratorTests.java @@ -172,7 +172,7 @@ class InstanceSupplierCodeGeneratorTests { instanceSupplier); assertThat(bean).isInstanceOf(TestBeanWithPrivateConstructor.class); assertThat(compiled.getSourceFile()) - .contains("return BeanInstanceSupplier.forConstructor();"); + .contains("return BeanInstanceSupplier.forConstructor();"); }); assertThat(getReflectionHints().getTypeHint(TestBeanWithPrivateConstructor.class)) .satisfies(hasConstructorWithMode(ExecutableMode.INVOKE)); @@ -211,7 +211,7 @@ class InstanceSupplierCodeGeneratorTests { assertThat(bean).isInstanceOf(String.class); assertThat(bean).isEqualTo("Hello"); assertThat(compiled.getSourceFile()) - .contains("BeanInstanceSupplier.forFactoryMethod") + .contains("forFactoryMethod") .doesNotContain("withGenerator"); }); assertThat(getReflectionHints().getTypeHint(SimpleConfiguration.class)) @@ -325,7 +325,7 @@ class InstanceSupplierCodeGeneratorTests { .addStatement("return $L", generatedCode).build()); }); this.generationContext.writeGeneratedContent(); - TestCompiler.forSystem().withFiles(this.generatedFiles).compile(compiled -> + TestCompiler.forSystem().withFiles(this.generatedFiles).printFiles(System.out).compile(compiled -> result.accept((InstanceSupplier) compiled.getInstance(Supplier.class).get(), compiled)); } diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/aot/TestBeanConfiguration.java b/spring-beans/src/test/java/org/springframework/beans/factory/aot/TestBeanConfiguration.java new file mode 100644 index 00000000000..6b848fe4d10 --- /dev/null +++ b/spring-beans/src/test/java/org/springframework/beans/factory/aot/TestBeanConfiguration.java @@ -0,0 +1,32 @@ +/* + * Copyright 2002-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.aot; + +import org.springframework.beans.testfixture.beans.TestBean; + +/** + * Test {@code @Configuration} style class to create {@link TestBean}. + * + * @author Phillip Webb + */ +public class TestBeanConfiguration { + + public TestBean testBean() { + return new TestBean(); + } + +}