Skip to content

Commit 28dd620

Browse files
committed
ContainerConnectionDetails should inherit qualifiers from Container bean
See #42970 (comment)
1 parent fdf24c6 commit 28dd620

File tree

3 files changed

+50
-0
lines changed

3 files changed

+50
-0
lines changed

spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/BeanOrigin.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,26 @@
2525
* {@link Origin} backed by a Spring Bean.
2626
*
2727
* @author Phillip Webb
28+
* @author Yanming Zhou
2829
*/
2930
class BeanOrigin implements Origin {
3031

3132
private final String beanName;
3233

34+
private final BeanDefinition beanDefinition;
35+
3336
private final String resourceDescription;
3437

3538
BeanOrigin(String beanName, BeanDefinition beanDefinition) {
3639
this.beanName = beanName;
40+
this.beanDefinition = beanDefinition;
3741
this.resourceDescription = (beanDefinition != null) ? beanDefinition.getResourceDescription() : null;
3842
}
3943

44+
BeanDefinition getBeanDefinition() {
45+
return this.beanDefinition;
46+
}
47+
4048
@Override
4149
public boolean equals(Object obj) {
4250
if (this == obj) {

spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ConnectionDetailsRegistrar.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
import org.springframework.beans.factory.ListableBeanFactory;
3131
import org.springframework.beans.factory.aot.BeanRegistrationExcludeFilter;
32+
import org.springframework.beans.factory.config.BeanDefinition;
3233
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
3334
import org.springframework.beans.factory.support.RegisteredBean;
3435
import org.springframework.beans.factory.support.RootBeanDefinition;
@@ -49,6 +50,7 @@
4950
* @author Moritz Halbritter
5051
* @author Andy Wilkinson
5152
* @author Phillip Webb
53+
* @author Yanming Zhou
5254
*/
5355
class ConnectionDetailsRegistrar {
5456

@@ -109,9 +111,22 @@ private <T> void registerBeanDefinition(BeanDefinitionRegistry registry, Contain
109111
RootBeanDefinition beanDefinition = new RootBeanDefinition(beanType, beanSupplier);
110112
beanDefinition.setAttribute(ServiceConnection.class.getName(), true);
111113
containerMetadata.addTo(beanDefinition);
114+
if (source.getOrigin() instanceof BeanOrigin beanOrigin) {
115+
inheritQualifiers(beanOrigin.getBeanDefinition(), beanDefinition);
116+
}
112117
registry.registerBeanDefinition(beanName, beanDefinition);
113118
}
114119

120+
private void inheritQualifiers(BeanDefinition origin, RootBeanDefinition derived) {
121+
derived.setPrimary(origin.isPrimary());
122+
derived.setFallback(origin.isFallback());
123+
derived.setAutowireCandidate(origin.isAutowireCandidate());
124+
if (origin instanceof RootBeanDefinition rbd) {
125+
derived.setDefaultCandidate(rbd.isDefaultCandidate());
126+
derived.setQualifiedElement(rbd.getQualifiedElement());
127+
}
128+
}
129+
115130
private String getBeanName(ContainerConnectionSource<?> source, ConnectionDetails connectionDetails) {
116131
List<String> parts = new ArrayList<>();
117132
parts.add(ClassUtils.getShortNameAsProperty(connectionDetails.getClass()));

spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/ConnectionDetailsRegistrarTests.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
* Tests for {@link ConnectionDetailsRegistrar}.
4141
*
4242
* @author Phillip Webb
43+
* @author Yanming Zhou
4344
*/
4445
class ConnectionDetailsRegistrarTests {
4546

@@ -106,6 +107,32 @@ void registerBeanDefinitionsRegistersDefinition() {
106107
assertThat(beanFactory.getBean(TestConnectionDetails.class)).isNotNull();
107108
}
108109

110+
@Test
111+
void containerConnectionDetailsBeanShouldInheritQualifiersFromContainerBean() {
112+
RootBeanDefinition originBeanDefinition = new RootBeanDefinition();
113+
originBeanDefinition.setPrimary(true);
114+
originBeanDefinition.setFallback(false);
115+
originBeanDefinition.setAutowireCandidate(true);
116+
originBeanDefinition.setDefaultCandidate(true);
117+
originBeanDefinition.setQualifiedElement(ConnectionDetailsRegistrarTests.class);
118+
Origin origin = new BeanOrigin("test", originBeanDefinition);
119+
ContainerConnectionSource<?> source = new ContainerConnectionSource<>("test", origin, PostgreSQLContainer.class,
120+
null, this.annotation, () -> this.container);
121+
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
122+
ConnectionDetailsRegistrar registrar = new ConnectionDetailsRegistrar(beanFactory, this.factories);
123+
given(this.factories.getConnectionDetails(source, true))
124+
.willReturn(Map.of(TestConnectionDetails.class, new TestConnectionDetails()));
125+
registrar.registerBeanDefinitions(beanFactory, source);
126+
String[] beanNames = beanFactory.getBeanNamesForType(TestConnectionDetails.class);
127+
assertThat(beanNames).hasSize(1);
128+
RootBeanDefinition beanDefinition = (RootBeanDefinition) beanFactory.getBeanDefinition(beanNames[0]);
129+
assertThat(beanDefinition.isPrimary()).isEqualTo(originBeanDefinition.isPrimary());
130+
assertThat(beanDefinition.isFallback()).isEqualTo(originBeanDefinition.isFallback());
131+
assertThat(beanDefinition.isAutowireCandidate()).isEqualTo(originBeanDefinition.isAutowireCandidate());
132+
assertThat(beanDefinition.isDefaultCandidate()).isEqualTo(originBeanDefinition.isDefaultCandidate());
133+
assertThat(beanDefinition.getQualifiedElement()).isEqualTo(originBeanDefinition.getQualifiedElement());
134+
}
135+
109136
static class TestConnectionDetails implements ConnectionDetails {
110137

111138
}

0 commit comments

Comments
 (0)