Skip to content

Commit 24dce34

Browse files
Schäfer, H.H. (Hans Hosea)Schäfer, H.H. (Hans Hosea)
authored andcommitted
35626: defaultCandidate for scoped proxies
Signed-off-by: Schäfer, H.H. (Hans Hosea) <[email protected]>
1 parent 2591cab commit 24dce34

File tree

3 files changed

+88
-0
lines changed

3 files changed

+88
-0
lines changed

spring-aop/src/main/java/org/springframework/aop/scope/ScopedProxyUtils.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,15 @@ public static BeanDefinitionHolder createScopedProxy(BeanDefinitionHolder defini
8181
// Copy autowire settings from original bean definition.
8282
proxyDefinition.setAutowireCandidate(targetDefinition.isAutowireCandidate());
8383
proxyDefinition.setPrimary(targetDefinition.isPrimary());
84+
proxyDefinition.setDefaultCandidate(targetDefinition.isDefaultCandidate());
8485
if (targetDefinition instanceof AbstractBeanDefinition abd) {
8586
proxyDefinition.copyQualifiersFrom(abd);
8687
}
8788

8889
// The target bean should be ignored in favor of the scoped proxy.
8990
targetDefinition.setAutowireCandidate(false);
9091
targetDefinition.setPrimary(false);
92+
targetDefinition.setDefaultCandidate(false);
9193

9294
// Register the target bean as separate bean in the factory.
9395
registry.registerBeanDefinition(targetBeanName, targetDefinition);

spring-aop/src/test/java/org/springframework/aop/scope/ScopedProxyUtilsTests.java

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,18 @@
1818

1919
import org.junit.jupiter.api.Test;
2020

21+
import org.springframework.beans.factory.config.BeanDefinition;
22+
import org.springframework.beans.factory.config.BeanDefinitionHolder;
23+
import org.springframework.beans.factory.support.AutowireCandidateQualifier;
24+
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
25+
import org.springframework.beans.factory.support.GenericBeanDefinition;
26+
import org.springframework.beans.factory.support.RootBeanDefinition;
27+
import org.springframework.beans.factory.support.SimpleBeanDefinitionRegistry;
28+
2129
import static org.assertj.core.api.Assertions.assertThat;
2230
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
2331

32+
2433
/**
2534
* Tests for {@link ScopedProxyUtils}.
2635
*
@@ -64,4 +73,66 @@ void getOriginalBeanNameForNonScopedTarget() {
6473
.withMessage("bean name 'myBean' does not refer to the target of a scoped proxy");
6574
}
6675

76+
@Test
77+
void createScopedProxyTargetOvertakesAutowireSettingsToProxyBeanDefinition() {
78+
final BeanDefinition targetDefinition = new GenericBeanDefinition();
79+
// Opposite of defaults
80+
targetDefinition.setAutowireCandidate(false);
81+
targetDefinition.setDefaultCandidate(false);
82+
targetDefinition.setPrimary(true);
83+
84+
final BeanDefinitionRegistry registry = new SimpleBeanDefinitionRegistry();
85+
final BeanDefinitionHolder proxyHolder = ScopedProxyUtils.createScopedProxy(new BeanDefinitionHolder(targetDefinition, "myBean"), registry, false);
86+
assertThat(proxyHolder).isNotNull();
87+
final BeanDefinition proxyBeanDefinition = proxyHolder.getBeanDefinition();
88+
assertThat(proxyBeanDefinition).isNotNull();
89+
90+
assertThat(proxyBeanDefinition.isAutowireCandidate()).isFalse();
91+
assertThat(proxyBeanDefinition.isDefaultCandidate()).isFalse();
92+
assertThat(proxyBeanDefinition.isPrimary()).isTrue();
93+
}
94+
95+
@Test
96+
void createScopedProxyTargetOvertakesBeanAttributesToProxyBeanDefinition() {
97+
final GenericBeanDefinition targetDefinition = new GenericBeanDefinition();
98+
// Opposite of defaults
99+
targetDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
100+
targetDefinition.setSource("theSource");
101+
targetDefinition.addQualifier(new AutowireCandidateQualifier("myQualifier"));
102+
103+
final BeanDefinitionRegistry registry = new SimpleBeanDefinitionRegistry();
104+
final BeanDefinitionHolder proxyHolder = ScopedProxyUtils.createScopedProxy(new BeanDefinitionHolder(targetDefinition, "myBean"), registry, false);
105+
assertThat(proxyHolder).isNotNull();
106+
final BeanDefinition proxyBeanDefinition = proxyHolder.getBeanDefinition();
107+
assertThat(proxyBeanDefinition).isNotNull();
108+
109+
assertThat(proxyBeanDefinition.getRole()).isEqualTo(BeanDefinition.ROLE_INFRASTRUCTURE);
110+
assertThat(proxyBeanDefinition).isInstanceOf(RootBeanDefinition.class);
111+
assertThat(proxyBeanDefinition.getPropertyValues()).hasSize(2);
112+
assertThat(proxyBeanDefinition.getPropertyValues().get("proxyTargetClass")).isEqualTo(false);
113+
assertThat(proxyBeanDefinition.getPropertyValues().get("targetBeanName")).isEqualTo(ScopedProxyUtils.getTargetBeanName("myBean"));
114+
115+
final RootBeanDefinition rootBeanDefinition = (RootBeanDefinition) proxyBeanDefinition;
116+
assertThat(rootBeanDefinition.getQualifiers()).hasSize(1);
117+
assertThat(rootBeanDefinition.hasQualifier("myQualifier")).isTrue();
118+
assertThat(rootBeanDefinition.getSource()).isEqualTo("theSource");
119+
}
120+
121+
@Test
122+
void createScopedProxyTargetCleansAutowireSettingsInTargetDefinition() {
123+
final BeanDefinition targetDefinition = new GenericBeanDefinition();
124+
targetDefinition.setAutowireCandidate(true);
125+
targetDefinition.setDefaultCandidate(true);
126+
targetDefinition.setPrimary(true);
127+
128+
final BeanDefinitionRegistry registry = new SimpleBeanDefinitionRegistry();
129+
final BeanDefinitionHolder proxyHolder = ScopedProxyUtils.createScopedProxy(new BeanDefinitionHolder(targetDefinition, "myBean"), registry, false);
130+
assertThat(proxyHolder).isNotNull();
131+
final BeanDefinition proxyBeanDefinition = proxyHolder.getBeanDefinition();
132+
assertThat(proxyBeanDefinition).isNotNull();
133+
134+
assertThat(targetDefinition.isAutowireCandidate()).isFalse();
135+
assertThat(targetDefinition.isDefaultCandidate()).isFalse();
136+
assertThat(targetDefinition.isPrimary()).isFalse();
137+
}
67138
}

spring-beans/src/main/java/org/springframework/beans/factory/config/BeanDefinition.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,21 @@ public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
177177
*/
178178
boolean isAutowireCandidate();
179179

180+
181+
/**
182+
* Sets whether this bean is a candidate for getting autowired into some other bean based on
183+
* the plain type, without any further indications such as a qualifier match.
184+
*/
185+
default void setDefaultCandidate(boolean defaultCandidate) {}
186+
187+
/**
188+
* Return wheter this bean is a candidate for getting autowired into some other bean based on
189+
* the plain type, without any further indications such as a qualifier match.
190+
*/
191+
default boolean isDefaultCandidate() {
192+
return true;
193+
}
194+
180195
/**
181196
* Set whether this bean is a primary autowire candidate.
182197
* <p>If this value is {@code true} for exactly one bean among multiple

0 commit comments

Comments
 (0)