diff --git a/spring-di-4/pom.xml b/spring-di-4/pom.xml
index a486b19e517d..b9cd10dcf398 100644
--- a/spring-di-4/pom.xml
+++ b/spring-di-4/pom.xml
@@ -33,6 +33,14 @@
com.baeldung.registrypostprocessor.RegistryPostProcessorApplication
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ 17
+
+
\ No newline at end of file
diff --git a/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/candidates/GoodService.java b/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/candidates/GoodService.java
new file mode 100644
index 000000000000..7f7208998dbd
--- /dev/null
+++ b/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/candidates/GoodService.java
@@ -0,0 +1,6 @@
+package com.baeldung.autowiremultipleimplementations.candidates;
+
+public interface GoodService {
+
+ String getHelloMessage();
+}
diff --git a/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/candidates/GoodServiceA.java b/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/candidates/GoodServiceA.java
new file mode 100644
index 000000000000..5815153fdca4
--- /dev/null
+++ b/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/candidates/GoodServiceA.java
@@ -0,0 +1,18 @@
+package com.baeldung.autowiremultipleimplementations.candidates;
+
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.annotation.Profile;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Service;
+
+@Service
+@Profile("default")
+@Qualifier("goodServiceA-custom-name")
+@Order(3)
+public class GoodServiceA implements GoodService {
+
+ @Override
+ public String getHelloMessage() {
+ return "Hello from A!";
+ }
+}
diff --git a/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/candidates/GoodServiceB.java b/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/candidates/GoodServiceB.java
new file mode 100644
index 000000000000..daa3a2bf179b
--- /dev/null
+++ b/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/candidates/GoodServiceB.java
@@ -0,0 +1,16 @@
+package com.baeldung.autowiremultipleimplementations.candidates;
+
+import org.springframework.context.annotation.Profile;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Service;
+
+@Service
+@Profile("default")
+@Order(2)
+public class GoodServiceB implements GoodService {
+
+ @Override
+ public String getHelloMessage() {
+ return "Hello from B!";
+ }
+}
diff --git a/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/candidates/GoodServiceC.java b/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/candidates/GoodServiceC.java
new file mode 100644
index 000000000000..9c8f799a37d9
--- /dev/null
+++ b/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/candidates/GoodServiceC.java
@@ -0,0 +1,18 @@
+package com.baeldung.autowiremultipleimplementations.candidates;
+
+import org.springframework.context.annotation.Primary;
+import org.springframework.context.annotation.Profile;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Service;
+
+@Primary
+@Service
+@Profile("default")
+@Order(1)
+public class GoodServiceC implements GoodService {
+
+ @Override
+ public String getHelloMessage() {
+ return "Hello from C!";
+ }
+}
diff --git a/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/candidates/GoodServiceD.java b/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/candidates/GoodServiceD.java
new file mode 100644
index 000000000000..8ebcdb474e70
--- /dev/null
+++ b/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/candidates/GoodServiceD.java
@@ -0,0 +1,13 @@
+package com.baeldung.autowiremultipleimplementations.candidates;
+
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
+
+@Service
+@Profile("dev")
+public class GoodServiceD implements GoodService {
+
+ public String getHelloMessage() {
+ return "Hello from D!";
+ }
+}
diff --git a/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/candidates/GoodServiceE.java b/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/candidates/GoodServiceE.java
new file mode 100644
index 000000000000..45c652681ad3
--- /dev/null
+++ b/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/candidates/GoodServiceE.java
@@ -0,0 +1,14 @@
+package com.baeldung.autowiremultipleimplementations.candidates;
+
+import com.baeldung.autowiremultipleimplementations.condition.OnFeatureEnabledCondition;
+import org.springframework.context.annotation.Conditional;
+import org.springframework.stereotype.Service;
+
+@Service
+@Conditional(OnFeatureEnabledCondition.class)
+public class GoodServiceE implements GoodService {
+
+ public String getHelloMessage() {
+ return "Hello from E!";
+ }
+}
diff --git a/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/components/CollectionsAutowire.java b/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/components/CollectionsAutowire.java
new file mode 100644
index 000000000000..ac2f15b2a807
--- /dev/null
+++ b/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/components/CollectionsAutowire.java
@@ -0,0 +1,35 @@
+package com.baeldung.autowiremultipleimplementations.components;
+
+import com.baeldung.autowiremultipleimplementations.candidates.GoodService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+import java.util.Set;
+
+@Component
+public class CollectionsAutowire {
+
+ private final Set goodServices;
+ private final Map goodServiceMap;
+
+ @Autowired
+ public CollectionsAutowire(Set goodServices, Map goodServiceMap) {
+ this.goodServices = goodServices;
+ this.goodServiceMap = goodServiceMap;
+ }
+
+ public String hello() {
+ return goodServices.stream()
+ .map(GoodService::getHelloMessage)
+ .reduce((a, b) -> a + " " + b)
+ .orElse("No services available");
+ }
+
+ public String helloMap() {
+ return goodServiceMap.values().stream()
+ .map(GoodService::getHelloMessage)
+ .reduce((a, b) -> a + " " + b)
+ .orElse("No services available");
+ }
+}
diff --git a/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/components/PrimaryAutowire.java b/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/components/PrimaryAutowire.java
new file mode 100644
index 000000000000..741cff5467ad
--- /dev/null
+++ b/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/components/PrimaryAutowire.java
@@ -0,0 +1,20 @@
+package com.baeldung.autowiremultipleimplementations.components;
+
+import com.baeldung.autowiremultipleimplementations.candidates.GoodService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class PrimaryAutowire {
+
+ private final GoodService goodService;
+
+ @Autowired
+ public PrimaryAutowire(GoodService goodService) {
+ this.goodService = goodService;
+ }
+
+ public String hello() {
+ return goodService.getHelloMessage();
+ }
+}
diff --git a/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/components/QualifierAutowire.java b/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/components/QualifierAutowire.java
new file mode 100644
index 000000000000..bf5f8ec8e7aa
--- /dev/null
+++ b/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/components/QualifierAutowire.java
@@ -0,0 +1,29 @@
+package com.baeldung.autowiremultipleimplementations.components;
+
+import com.baeldung.autowiremultipleimplementations.candidates.GoodService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Component;
+
+@Component
+public class QualifierAutowire {
+
+ private final GoodService goodServiceA;
+ private final GoodService goodServiceB;
+ private final GoodService goodServiceC;
+
+ @Autowired
+ public QualifierAutowire(@Qualifier("goodServiceA-custom-name") GoodService niceServiceA,
+ @Qualifier("goodServiceB") GoodService niceServiceB,
+ GoodService goodServiceC) {
+ this.goodServiceA = niceServiceA;
+ this.goodServiceB = niceServiceB;
+ this.goodServiceC = goodServiceC;
+ }
+
+ public String hello() {
+ return goodServiceA.getHelloMessage() + " " +
+ goodServiceB.getHelloMessage() + " " +
+ goodServiceC.getHelloMessage();
+ }
+}
diff --git a/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/condition/OnFeatureEnabledCondition.java b/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/condition/OnFeatureEnabledCondition.java
new file mode 100644
index 000000000000..f7ae0ab04edf
--- /dev/null
+++ b/spring-di-4/src/main/java/com/baeldung/autowiremultipleimplementations/condition/OnFeatureEnabledCondition.java
@@ -0,0 +1,14 @@
+package com.baeldung.autowiremultipleimplementations.condition;
+
+import org.springframework.context.annotation.Condition;
+import org.springframework.context.annotation.ConditionContext;
+import org.springframework.core.type.AnnotatedTypeMetadata;
+
+public class OnFeatureEnabledCondition implements Condition {
+
+ @Override
+ public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
+ String featureToggle = context.getEnvironment().getProperty("feature.toggle");
+ return "enabled".equalsIgnoreCase(featureToggle);
+ }
+}
diff --git a/spring-di-4/src/test/java/com/baeldung/autowiremultipleimplementations/CollectionsAutowireUnitTest.java b/spring-di-4/src/test/java/com/baeldung/autowiremultipleimplementations/CollectionsAutowireUnitTest.java
new file mode 100644
index 000000000000..c8eda9094469
--- /dev/null
+++ b/spring-di-4/src/test/java/com/baeldung/autowiremultipleimplementations/CollectionsAutowireUnitTest.java
@@ -0,0 +1,75 @@
+package com.baeldung.autowiremultipleimplementations;
+
+import com.baeldung.autowiremultipleimplementations.components.CollectionsAutowire;
+import com.baeldung.autowiremultipleimplementations.candidates.*;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import java.lang.reflect.Field;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(classes = {CollectionsAutowire.class, GoodServiceD.class, GoodServiceC.class, GoodServiceB.class, GoodServiceA.class})
+public class CollectionsAutowireUnitTest {
+
+ @Autowired
+ private CollectionsAutowire collectionsAutowire;
+
+ @Test
+ public void testSetAutowiring() throws NoSuchFieldException, IllegalAccessException {
+ Set> rawServices = (Set>) getPrivateField(collectionsAutowire, "goodServices");
+ assertNotNull(rawServices, "Set of GoodService should not be null");
+ assertFalse(rawServices.isEmpty(), "Set of GoodService should not be empty");
+
+ Set services = rawServices.stream()
+ .map(service -> (GoodService) service)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toSet());
+
+ // Check for all specific types
+ assertTrue(services.stream().anyMatch(s -> s instanceof GoodServiceA), "Should contain GoodServiceA");
+ assertTrue(services.stream().anyMatch(s -> s instanceof GoodServiceB), "Should contain GoodServiceB");
+ assertTrue(services.stream().anyMatch(s -> s instanceof GoodServiceC), "Should contain GoodServiceC");
+
+ String actualMessage = collectionsAutowire.hello();
+ assertTrue(actualMessage.contains("Hello from A!"), "Message should contain greeting from A");
+ assertTrue(actualMessage.contains("Hello from B!"), "Message should contain greeting from B");
+ assertTrue(actualMessage.contains("Hello from C!"), "Message should contain greeting from C");
+ }
+
+ @Test
+ public void testMapAutowiring() throws NoSuchFieldException, IllegalAccessException {
+ Map, ?> rawServiceMap = (Map, ?>) getPrivateField(collectionsAutowire, "goodServiceMap");
+ assertNotNull(rawServiceMap, "Map of GoodService should not be null");
+ assertFalse(rawServiceMap.isEmpty(), "Map of GoodService should not be empty");
+
+ Map serviceMap = rawServiceMap.entrySet().stream()
+ .collect(Collectors.toMap(
+ entry -> (String) entry.getKey(),
+ entry -> (GoodService) entry.getValue()
+ ));
+
+ // Check keys and specific instances
+ assertTrue(serviceMap.containsKey("goodServiceA"), "Map should contain a key for GoodServiceA");
+ assertTrue(serviceMap.containsKey("goodServiceB"), "Map should contain a key for GoodServiceB");
+ assertTrue(serviceMap.containsKey("goodServiceC"), "Map should contain a key for GoodServiceC");
+
+ assertInstanceOf(GoodServiceA.class, serviceMap.get("goodServiceA"), "goodServiceA should be an instance of GoodServiceA");
+ assertInstanceOf(GoodServiceB.class, serviceMap.get("goodServiceB"), "goodServiceB should be an instance of GoodServiceB");
+ assertInstanceOf(GoodServiceC.class, serviceMap.get("goodServiceC"), "goodServiceC should be an instance of GoodServiceC");
+ }
+
+ private Object getPrivateField(Object object, String fieldName) throws NoSuchFieldException, IllegalAccessException {
+ Field field = object.getClass().getDeclaredField(fieldName);
+ field.setAccessible(true);
+ return field.get(object);
+ }
+}
diff --git a/spring-di-4/src/test/java/com/baeldung/autowiremultipleimplementations/ConditionalDisabledUnitTest.java b/spring-di-4/src/test/java/com/baeldung/autowiremultipleimplementations/ConditionalDisabledUnitTest.java
new file mode 100644
index 000000000000..c4095915a64d
--- /dev/null
+++ b/spring-di-4/src/test/java/com/baeldung/autowiremultipleimplementations/ConditionalDisabledUnitTest.java
@@ -0,0 +1,26 @@
+package com.baeldung.autowiremultipleimplementations;
+
+import com.baeldung.autowiremultipleimplementations.candidates.GoodService;
+import com.baeldung.autowiremultipleimplementations.candidates.GoodServiceE;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(classes = {GoodServiceE.class})
+@TestPropertySource(properties = {"feature.toggle=disabled"})
+public class ConditionalDisabledUnitTest {
+
+ @Autowired(required = false)
+ private GoodService goodService;
+
+ @Test
+ void testServiceWhenFeatureDisabled() {
+ assertNull(goodService, "GoodService should not be autowired when feature.toggle is disabled");
+ }
+}
diff --git a/spring-di-4/src/test/java/com/baeldung/autowiremultipleimplementations/ConditionalEnabledUnitTest.java b/spring-di-4/src/test/java/com/baeldung/autowiremultipleimplementations/ConditionalEnabledUnitTest.java
new file mode 100644
index 000000000000..d186aa678ece
--- /dev/null
+++ b/spring-di-4/src/test/java/com/baeldung/autowiremultipleimplementations/ConditionalEnabledUnitTest.java
@@ -0,0 +1,27 @@
+package com.baeldung.autowiremultipleimplementations;
+
+import com.baeldung.autowiremultipleimplementations.candidates.GoodService;
+import com.baeldung.autowiremultipleimplementations.candidates.GoodServiceE;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(classes = {GoodServiceE.class})
+@TestPropertySource(properties = {"feature.toggle=enabled"})
+public class ConditionalEnabledUnitTest {
+
+ @Autowired
+ private GoodService goodService;
+
+ @Test
+ void testServiceWhenFeatureEnabled() {
+ assertNotNull(goodService, "GoodService should be autowired when feature.toggle is enabled");
+ assertInstanceOf(GoodServiceE.class, goodService, "goodService should be an instance of GoodServiceE");
+ }
+}
diff --git a/spring-di-4/src/test/java/com/baeldung/autowiremultipleimplementations/PrimaryAutowireUnitTest.java b/spring-di-4/src/test/java/com/baeldung/autowiremultipleimplementations/PrimaryAutowireUnitTest.java
new file mode 100644
index 000000000000..491226174351
--- /dev/null
+++ b/spring-di-4/src/test/java/com/baeldung/autowiremultipleimplementations/PrimaryAutowireUnitTest.java
@@ -0,0 +1,38 @@
+package com.baeldung.autowiremultipleimplementations;
+
+import com.baeldung.autowiremultipleimplementations.components.PrimaryAutowire;
+import com.baeldung.autowiremultipleimplementations.candidates.GoodService;
+import com.baeldung.autowiremultipleimplementations.candidates.GoodServiceA;
+import com.baeldung.autowiremultipleimplementations.candidates.GoodServiceB;
+import com.baeldung.autowiremultipleimplementations.candidates.GoodServiceC;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.ApplicationContext;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+@SpringBootTest(classes = {PrimaryAutowire.class, GoodServiceC.class, GoodServiceB.class, GoodServiceA.class})
+@ExtendWith(SpringExtension.class)
+public class PrimaryAutowireUnitTest {
+
+ @Autowired
+ private ApplicationContext context;
+
+ @Autowired
+ private PrimaryAutowire primaryAutowire;
+
+ @Test
+ public void whenPrimaryServiceInjected_thenItShouldBeGoodServiceC() {
+ GoodService injectedService = context.getBean(GoodService.class);
+
+ assertInstanceOf(GoodServiceC.class, injectedService);
+
+ String expectedMessage = "Hello from C!"; // GoodServiceC returns this message
+ String actualMessage = primaryAutowire.hello();
+
+ assertEquals(expectedMessage, actualMessage);
+ }
+}
diff --git a/spring-di-4/src/test/java/com/baeldung/autowiremultipleimplementations/ProfilesAutowireUnitTest.java b/spring-di-4/src/test/java/com/baeldung/autowiremultipleimplementations/ProfilesAutowireUnitTest.java
new file mode 100644
index 000000000000..028a4a92583e
--- /dev/null
+++ b/spring-di-4/src/test/java/com/baeldung/autowiremultipleimplementations/ProfilesAutowireUnitTest.java
@@ -0,0 +1,29 @@
+package com.baeldung.autowiremultipleimplementations;
+
+import com.baeldung.autowiremultipleimplementations.components.PrimaryAutowire;
+import com.baeldung.autowiremultipleimplementations.candidates.*;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(classes = {PrimaryAutowire.class, GoodServiceD.class, GoodServiceC.class,
+ GoodServiceB.class, GoodServiceA.class})
+@ActiveProfiles("dev")
+public class ProfilesAutowireUnitTest {
+
+ @Autowired
+ private GoodService goodService;
+
+ @Test
+ public void goodServiceDIsAutowiredCorrectly() {
+ assertNotNull(goodService, "GoodService should be autowired");
+ assertInstanceOf(GoodServiceD.class, goodService,
+ "Autowired GoodService should be an instance of GoodServiceD under 'dev' profile");
+ }
+}
diff --git a/spring-di-4/src/test/java/com/baeldung/autowiremultipleimplementations/QualifierAutowireUnitTest.java b/spring-di-4/src/test/java/com/baeldung/autowiremultipleimplementations/QualifierAutowireUnitTest.java
new file mode 100644
index 000000000000..ab756ecea426
--- /dev/null
+++ b/spring-di-4/src/test/java/com/baeldung/autowiremultipleimplementations/QualifierAutowireUnitTest.java
@@ -0,0 +1,49 @@
+package com.baeldung.autowiremultipleimplementations;
+
+import com.baeldung.autowiremultipleimplementations.components.QualifierAutowire;
+import com.baeldung.autowiremultipleimplementations.candidates.GoodService;
+import com.baeldung.autowiremultipleimplementations.candidates.GoodServiceA;
+import com.baeldung.autowiremultipleimplementations.candidates.GoodServiceB;
+import com.baeldung.autowiremultipleimplementations.candidates.GoodServiceC;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import java.lang.reflect.Field;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+@SpringBootTest(classes = {QualifierAutowire.class, GoodServiceC.class, GoodServiceB.class, GoodServiceA.class})
+@ExtendWith(SpringExtension.class)
+public class QualifierAutowireUnitTest {
+
+ @Autowired
+ private QualifierAutowire qualifierAutowire;
+
+ @Test
+ public void testAutowiring() throws NoSuchFieldException, IllegalAccessException {
+ assertNotNull(qualifierAutowire, "QualifierAutowire should be autowired");
+
+ GoodService goodServiceA = getGoodServiceField("goodServiceA");
+ GoodService goodServiceB = getGoodServiceField("goodServiceB");
+ GoodService goodServiceC = getGoodServiceField("goodServiceC");
+
+ // Verify the types of the autowired services
+ assertInstanceOf(GoodServiceA.class, goodServiceA, "goodServiceA should be an instance of GoodServiceA");
+ assertInstanceOf(GoodServiceB.class, goodServiceB, "goodServiceB should be an instance of GoodServiceB");
+ assertInstanceOf(GoodServiceC.class, goodServiceC, "goodServiceC should be an instance of GoodServiceC");
+
+ // Check that the hello message is as expected
+ String expectedMessage = "Hello from A! Hello from B! Hello from C!";
+ String actualMessage = qualifierAutowire.hello();
+ assertEquals(expectedMessage, actualMessage, "Messages should be concatenated correctly from all services");
+ }
+
+ private GoodService getGoodServiceField(String fieldName) throws NoSuchFieldException, IllegalAccessException {
+ Field field = qualifierAutowire.getClass().getDeclaredField(fieldName);
+ field.setAccessible(true);
+ return (GoodService) field.get(qualifierAutowire);
+ }
+}