From cc530d4df2e265095142cd09341c7903f72dbbb3 Mon Sep 17 00:00:00 2001 From: Sam Brannen <104798+sbrannen@users.noreply.github.com> Date: Thu, 27 Nov 2025 11:37:46 +0100 Subject: [PATCH] Support RuntimeBeanReference(name, type) in AOT-generated code The RuntimeBeanReference(name, type) constructor was introduced in 7.0; however, BeanDefinitionPropertyValueCodeGeneratorDelegates in our AOT infrastructure was not updated to support the new constructor. This commit revises BeanDefinitionPropertyValueCodeGeneratorDelegates to ensure that AOT generated code for a RuntimeBeanReference uses the RuntimeBeanReference(name, type) constructor, thereby retaining the originally configured bean name. See gh-35101 Closes gh-35913 --- ...onPropertyValueCodeGeneratorDelegates.java | 4 +-- ...pertyValueCodeGeneratorDelegatesTests.java | 30 +++++++++++++------ 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionPropertyValueCodeGeneratorDelegates.java b/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionPropertyValueCodeGeneratorDelegates.java index 6fc2e7c093b..30b38e496c1 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionPropertyValueCodeGeneratorDelegates.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionPropertyValueCodeGeneratorDelegates.java @@ -203,8 +203,8 @@ public abstract class BeanDefinitionPropertyValueCodeGeneratorDelegates { public @Nullable CodeBlock generateCode(ValueCodeGenerator valueCodeGenerator, Object value) { if (value instanceof RuntimeBeanReference runtimeBeanReference && runtimeBeanReference.getBeanType() != null) { - return CodeBlock.of("new $T($T.class)", RuntimeBeanReference.class, - runtimeBeanReference.getBeanType()); + return CodeBlock.of("new $T($S, $T.class)", RuntimeBeanReference.class, + runtimeBeanReference.getBeanName(), runtimeBeanReference.getBeanType()); } else if (value instanceof BeanReference beanReference) { return CodeBlock.of("new $T($S)", RuntimeBeanReference.class, diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionPropertyValueCodeGeneratorDelegatesTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionPropertyValueCodeGeneratorDelegatesTests.java index 0e24774cf03..39dd08c919b 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionPropertyValueCodeGeneratorDelegatesTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionPropertyValueCodeGeneratorDelegatesTests.java @@ -458,30 +458,42 @@ class BeanDefinitionPropertyValueCodeGeneratorDelegatesTests { class BeanReferenceTests { @Test - void generatedWhenBeanNameReference() { - RuntimeBeanNameReference beanReference = new RuntimeBeanNameReference("test"); + void generatedWhenRuntimeBeanNameReference() { + BeanReference beanReference = new RuntimeBeanNameReference("test"); compile(beanReference, (instance, compiler) -> { RuntimeBeanReference actual = (RuntimeBeanReference) instance; - assertThat(actual.getBeanName()).isEqualTo(beanReference.getBeanName()); + assertThat(actual.getBeanName()).as("name").isEqualTo("test"); + assertThat(actual.getBeanType()).as("type").isNull(); }); } @Test - void generatedWhenBeanReferenceByName() { - RuntimeBeanReference beanReference = new RuntimeBeanReference("test"); + void generatedWhenRuntimeBeanReferenceByName() { + BeanReference beanReference = new RuntimeBeanReference("test"); compile(beanReference, (instance, compiler) -> { RuntimeBeanReference actual = (RuntimeBeanReference) instance; - assertThat(actual.getBeanName()).isEqualTo(beanReference.getBeanName()); - assertThat(actual.getBeanType()).isEqualTo(beanReference.getBeanType()); + assertThat(actual.getBeanName()).as("name").isEqualTo("test"); + assertThat(actual.getBeanType()).as("type").isNull(); }); } @Test - void generatedWhenBeanReferenceByType() { + void generatedWhenRuntimeBeanReferenceByType() { BeanReference beanReference = new RuntimeBeanReference(String.class); compile(beanReference, (instance, compiler) -> { RuntimeBeanReference actual = (RuntimeBeanReference) instance; - assertThat(actual.getBeanType()).isEqualTo(String.class); + assertThat(actual.getBeanName()).as("name").isEqualTo(String.class.getName()); + assertThat(actual.getBeanType()).as("type").isEqualTo(String.class); + }); + } + + @Test // gh-35913 + void generatedWhenRuntimeBeanReferenceByNameAndType() { + BeanReference beanReference = new RuntimeBeanReference("test", String.class); + compile(beanReference, (instance, compiler) -> { + RuntimeBeanReference actual = (RuntimeBeanReference) instance; + assertThat(actual.getBeanName()).as("name").isEqualTo("test"); + assertThat(actual.getBeanType()).as("type").isEqualTo(String.class); }); }