Allow MethodReference to define a more flexible signature

This commit moves MethodReference to an interface with a default
implementation that relies on a MethodSpec. Such an arrangement avoid
the need of specifying attributes of the method such as whether it is
static or not.

The resolution of the invocation block now takes an
ArgumentCodeGenerator rather than the raw arguments. Doing so gives
the opportunity to create more flexible signatures.

See gh-29005
This commit is contained in:
Stephane Nicoll
2022-08-24 07:53:38 +02:00
parent 8a4a89b9d9
commit ae706f3954
16 changed files with 469 additions and 428 deletions

View File

@@ -27,6 +27,7 @@ import org.assertj.core.api.InstanceOfAssertFactories;
import org.junit.jupiter.api.Test;
import org.springframework.aot.generate.MethodReference;
import org.springframework.aot.generate.MethodReference.ArgumentCodeGenerator;
import org.springframework.aot.hint.ResourcePatternHint;
import org.springframework.aot.test.generate.TestGenerationContext;
import org.springframework.aot.test.generate.compile.Compiled;
@@ -162,11 +163,14 @@ class ConfigurationClassPostProcessorAotContributionTests {
private void compile(BiConsumer<Consumer<DefaultListableBeanFactory>, Compiled> result) {
MethodReference methodReference = this.beanFactoryInitializationCode.getInitializers().get(0);
this.beanFactoryInitializationCode.getTypeBuilder().set(type -> {
CodeBlock methodInvocation = methodReference.toInvokeCodeBlock(
ArgumentCodeGenerator.of(DefaultListableBeanFactory.class, "beanFactory"),
this.beanFactoryInitializationCode.getClassName());
type.addModifiers(Modifier.PUBLIC);
type.addSuperinterface(ParameterizedTypeName.get(Consumer.class, DefaultListableBeanFactory.class));
type.addMethod(MethodSpec.methodBuilder("accept").addModifiers(Modifier.PUBLIC)
.addParameter(DefaultListableBeanFactory.class, "beanFactory")
.addStatement(methodReference.toInvokeCodeBlock(CodeBlock.of("beanFactory")))
.addStatement(methodInvocation)
.build());
});
this.generationContext.writeGeneratedContent();