Add generics to BeanInstanceSupplier
Update `BeanInstanceSupplier` to support a generic type. See gh-28748
This commit is contained in:
@@ -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<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(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));
|
||||
}
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ class BeanInstanceSupplierTests {
|
||||
|
||||
@Test
|
||||
void forConstructorWhenNotFoundThrowsException() {
|
||||
BeanInstanceSupplier resolver = BeanInstanceSupplier
|
||||
BeanInstanceSupplier<InputStream> 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<Object> resolver = BeanInstanceSupplier.forConstructor(String.class);
|
||||
assertThat(resolver.getFactoryMethod()).isNull();
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ class BeanInstanceSupplierTests {
|
||||
|
||||
@Test
|
||||
void forFactoryMethodWhenNotFoundThrowsException() {
|
||||
BeanInstanceSupplier resolver = BeanInstanceSupplier
|
||||
BeanInstanceSupplier<InputStream> 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<String> 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<Object> resolver = BeanInstanceSupplier
|
||||
.forConstructor();
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> resolver.withGenerator(
|
||||
@@ -177,7 +177,7 @@ class BeanInstanceSupplierTests {
|
||||
|
||||
@Test
|
||||
void withGeneratorWhenFunctionIsNullThrowsException() {
|
||||
BeanInstanceSupplier resolver = BeanInstanceSupplier
|
||||
BeanInstanceSupplier<Object> resolver = BeanInstanceSupplier
|
||||
.forConstructor();
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> resolver.withGenerator(
|
||||
@@ -187,7 +187,7 @@ class BeanInstanceSupplierTests {
|
||||
|
||||
@Test
|
||||
void withGeneratorWhenSupplierIsNullThrowsException() {
|
||||
BeanInstanceSupplier resolver = BeanInstanceSupplier
|
||||
BeanInstanceSupplier<Object> resolver = BeanInstanceSupplier
|
||||
.forConstructor();
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> resolver.withGenerator(
|
||||
@@ -197,7 +197,7 @@ class BeanInstanceSupplierTests {
|
||||
|
||||
@Test
|
||||
void getWithConstructorDoesNotSetResolvedFactoryMethod() throws Exception {
|
||||
BeanInstanceSupplier resolver = BeanInstanceSupplier
|
||||
BeanInstanceSupplier<SingleArgConstructor> 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<String> 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<Object> result = new ArrayList<>();
|
||||
BeanInstanceSupplier resolver = BeanInstanceSupplier
|
||||
BeanInstanceSupplier<Object> 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<String> resolver = BeanInstanceSupplier
|
||||
.<String>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<String> resolver = BeanInstanceSupplier
|
||||
.<String>forConstructor(String.class)
|
||||
.withGenerator(() -> "1");
|
||||
assertThat(resolver.get(registerBean)).isInstanceOf(String.class).isEqualTo("1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenRegisteredBeanIsNullThrowsException() {
|
||||
BeanInstanceSupplier resolver = BeanInstanceSupplier
|
||||
BeanInstanceSupplier<Object> 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<Object> 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<Object> 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ class InstanceSupplierCodeGeneratorTests {
|
||||
instanceSupplier);
|
||||
assertThat(bean).isInstanceOf(TestBeanWithPrivateConstructor.class);
|
||||
assertThat(compiled.getSourceFile())
|
||||
.contains("return BeanInstanceSupplier.forConstructor();");
|
||||
.contains("return BeanInstanceSupplier.<TestBeanWithPrivateConstructor>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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user