From d733023a2978a4725c6686645ad2dc05e640266f Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 14 Oct 2025 19:17:57 +0200 Subject: [PATCH] Consistently apply fallback attribute to proxy definition as well See gh-35627 --- .../aop/scope/ScopedProxyUtils.java | 4 +- .../aop/scope/ScopedProxyUtilsTests.java | 59 ++++++++++--------- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/scope/ScopedProxyUtils.java b/spring-aop/src/main/java/org/springframework/aop/scope/ScopedProxyUtils.java index 004012b0123..411a47fa5fb 100644 --- a/spring-aop/src/main/java/org/springframework/aop/scope/ScopedProxyUtils.java +++ b/spring-aop/src/main/java/org/springframework/aop/scope/ScopedProxyUtils.java @@ -81,14 +81,16 @@ public abstract class ScopedProxyUtils { // Copy autowire settings from original bean definition. proxyDefinition.setAutowireCandidate(targetDefinition.isAutowireCandidate()); proxyDefinition.setPrimary(targetDefinition.isPrimary()); + proxyDefinition.setFallback(targetDefinition.isFallback()); if (targetDefinition instanceof AbstractBeanDefinition abd) { - proxyDefinition.copyQualifiersFrom(abd); proxyDefinition.setDefaultCandidate(abd.isDefaultCandidate()); + proxyDefinition.copyQualifiersFrom(abd); } // The target bean should be ignored in favor of the scoped proxy. targetDefinition.setAutowireCandidate(false); targetDefinition.setPrimary(false); + targetDefinition.setFallback(false); if (targetDefinition instanceof AbstractBeanDefinition abd) { abd.setDefaultCandidate(false); } diff --git a/spring-aop/src/test/java/org/springframework/aop/scope/ScopedProxyUtilsTests.java b/spring-aop/src/test/java/org/springframework/aop/scope/ScopedProxyUtilsTests.java index 164e6c85216..de5e76db2b7 100644 --- a/spring-aop/src/test/java/org/springframework/aop/scope/ScopedProxyUtilsTests.java +++ b/spring-aop/src/test/java/org/springframework/aop/scope/ScopedProxyUtilsTests.java @@ -30,11 +30,11 @@ import org.springframework.beans.factory.support.SimpleBeanDefinitionRegistry; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; - /** * Tests for {@link ScopedProxyUtils}. * * @author Sam Brannen + * @author Juergen Hoeller * @since 5.1.10 */ class ScopedProxyUtilsTests { @@ -63,58 +63,58 @@ class ScopedProxyUtilsTests { @Test void getOriginalBeanNameForNullTargetBean() { assertThatIllegalArgumentException() - .isThrownBy(() -> ScopedProxyUtils.getOriginalBeanName(null)) - .withMessage("bean name 'null' does not refer to the target of a scoped proxy"); + .isThrownBy(() -> ScopedProxyUtils.getOriginalBeanName(null)) + .withMessage("bean name 'null' does not refer to the target of a scoped proxy"); } @Test void getOriginalBeanNameForNonScopedTarget() { assertThatIllegalArgumentException() - .isThrownBy(() -> ScopedProxyUtils.getOriginalBeanName("myBean")) - .withMessage("bean name 'myBean' does not refer to the target of a scoped proxy"); + .isThrownBy(() -> ScopedProxyUtils.getOriginalBeanName("myBean")) + .withMessage("bean name 'myBean' does not refer to the target of a scoped proxy"); } @Test - void createScopedProxyTargetOvertakesAutowireSettingsToProxyBeanDefinition() { - final AbstractBeanDefinition targetDefinition = new GenericBeanDefinition(); + void createScopedProxyTargetAppliesAutowireSettingsToProxyBeanDefinition() { + AbstractBeanDefinition targetDefinition = new GenericBeanDefinition(); // Opposite of defaults targetDefinition.setAutowireCandidate(false); targetDefinition.setDefaultCandidate(false); targetDefinition.setPrimary(true); + targetDefinition.setFallback(true); - final BeanDefinitionRegistry registry = new SimpleBeanDefinitionRegistry(); - final BeanDefinitionHolder proxyHolder = ScopedProxyUtils.createScopedProxy(new BeanDefinitionHolder(targetDefinition, "myBean"), registry, false); - assertThat(proxyHolder).isNotNull(); - final BeanDefinition proxyBeanDefinition = proxyHolder.getBeanDefinition(); - assertThat(proxyBeanDefinition).isNotNull(); - assertThat(proxyBeanDefinition).isInstanceOf(RootBeanDefinition.class); + BeanDefinitionRegistry registry = new SimpleBeanDefinitionRegistry(); + BeanDefinitionHolder proxyHolder = ScopedProxyUtils.createScopedProxy( + new BeanDefinitionHolder(targetDefinition, "myBean"), registry, false); + AbstractBeanDefinition proxyBeanDefinition = (AbstractBeanDefinition) proxyHolder.getBeanDefinition(); assertThat(proxyBeanDefinition.isAutowireCandidate()).isFalse(); + assertThat(proxyBeanDefinition.isDefaultCandidate()).isFalse(); assertThat(proxyBeanDefinition.isPrimary()).isTrue(); - assertThat(((RootBeanDefinition)proxyBeanDefinition).isDefaultCandidate()).isFalse(); + assertThat(proxyBeanDefinition.isFallback()).isTrue(); } @Test - void createScopedProxyTargetOvertakesBeanAttributesToProxyBeanDefinition() { - final GenericBeanDefinition targetDefinition = new GenericBeanDefinition(); + void createScopedProxyTargetAppliesBeanAttributesToProxyBeanDefinition() { + GenericBeanDefinition targetDefinition = new GenericBeanDefinition(); // Opposite of defaults targetDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); targetDefinition.setSource("theSource"); targetDefinition.addQualifier(new AutowireCandidateQualifier("myQualifier")); - final BeanDefinitionRegistry registry = new SimpleBeanDefinitionRegistry(); - final BeanDefinitionHolder proxyHolder = ScopedProxyUtils.createScopedProxy(new BeanDefinitionHolder(targetDefinition, "myBean"), registry, false); - assertThat(proxyHolder).isNotNull(); - final BeanDefinition proxyBeanDefinition = proxyHolder.getBeanDefinition(); - assertThat(proxyBeanDefinition).isNotNull(); + BeanDefinitionRegistry registry = new SimpleBeanDefinitionRegistry(); + BeanDefinitionHolder proxyHolder = ScopedProxyUtils.createScopedProxy( + new BeanDefinitionHolder(targetDefinition, "myBean"), registry, false); + BeanDefinition proxyBeanDefinition = proxyHolder.getBeanDefinition(); assertThat(proxyBeanDefinition.getRole()).isEqualTo(BeanDefinition.ROLE_INFRASTRUCTURE); assertThat(proxyBeanDefinition).isInstanceOf(RootBeanDefinition.class); assertThat(proxyBeanDefinition.getPropertyValues()).hasSize(2); assertThat(proxyBeanDefinition.getPropertyValues().get("proxyTargetClass")).isEqualTo(false); - assertThat(proxyBeanDefinition.getPropertyValues().get("targetBeanName")).isEqualTo(ScopedProxyUtils.getTargetBeanName("myBean")); + assertThat(proxyBeanDefinition.getPropertyValues().get("targetBeanName")).isEqualTo( + ScopedProxyUtils.getTargetBeanName("myBean")); - final RootBeanDefinition rootBeanDefinition = (RootBeanDefinition) proxyBeanDefinition; + RootBeanDefinition rootBeanDefinition = (RootBeanDefinition) proxyBeanDefinition; assertThat(rootBeanDefinition.getQualifiers()).hasSize(1); assertThat(rootBeanDefinition.hasQualifier("myQualifier")).isTrue(); assertThat(rootBeanDefinition.getSource()).isEqualTo("theSource"); @@ -122,19 +122,20 @@ class ScopedProxyUtilsTests { @Test void createScopedProxyTargetCleansAutowireSettingsInTargetDefinition() { - final AbstractBeanDefinition targetDefinition = new GenericBeanDefinition(); + AbstractBeanDefinition targetDefinition = new GenericBeanDefinition(); targetDefinition.setAutowireCandidate(true); targetDefinition.setDefaultCandidate(true); targetDefinition.setPrimary(true); + targetDefinition.setFallback(true); - final BeanDefinitionRegistry registry = new SimpleBeanDefinitionRegistry(); - final BeanDefinitionHolder proxyHolder = ScopedProxyUtils.createScopedProxy(new BeanDefinitionHolder(targetDefinition, "myBean"), registry, false); - assertThat(proxyHolder).isNotNull(); - final BeanDefinition proxyBeanDefinition = proxyHolder.getBeanDefinition(); - assertThat(proxyBeanDefinition).isNotNull(); + BeanDefinitionRegistry registry = new SimpleBeanDefinitionRegistry(); + ScopedProxyUtils.createScopedProxy( + new BeanDefinitionHolder(targetDefinition, "myBean"), registry, false); assertThat(targetDefinition.isAutowireCandidate()).isFalse(); assertThat(targetDefinition.isDefaultCandidate()).isFalse(); assertThat(targetDefinition.isPrimary()).isFalse(); + assertThat(targetDefinition.isFallback()).isFalse(); } + }