I have a similar question here
Guice with multiple concretes......picking one of them
with a solution for Guice.
But I have a different project usin
I think I have something that works:
beans.xml (note the "util" extras in the namespace declares)
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.5.xsd">
<bean id="theLoggerBean"
class="org.apache.commons.logging.impl.Log4JLogger">
<constructor-arg value="log" />
</bean>
<bean id="fedExShipperBean"
class="com.me.shipping.FedExShipper">
<constructor-arg ref="theLoggerBean"></constructor-arg>
</bean>
<bean id="upsShipperBean"
class="com.me.shipping.UpsShipper">
<constructor-arg ref="theLoggerBean"></constructor-arg>
</bean>
<bean id="uspsShipperBean"
class="com.me.shipping.UspsShipper">
<constructor-arg ref="theLoggerBean"></constructor-arg>
</bean>
<util:map id="shipperInterfaceMap" key-type="java.lang.String"
value-type="com.me.shipping.interfaces.ShipperInterface">
<entry key="fedexFriendlyName" value-ref="fedExShipperBean" />
<entry key="upsFriendlyName" value-ref="upsShipperBean" />
<entry key="uspsFriendlyName" value-ref="uspsShipperBean" />
</util:map>
<bean id="orderProcessorImplBean"
class="com.me.shipping.OrderProcessorImpl">
<constructor-arg ref="theLoggerBean"></constructor-arg>
<constructor-arg ref="shipperInterfaceMap"></constructor-arg>
</bean>
</beans>
and java
package com.me.shipping;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import com.me.shipping.interfaces.OrderProcessorInterface;
import com.me.shipping.interfaces.ShipperInterface;
import com.me.Models.Order;
public class OrderProcessorImpl implements OrderProcessorInterface {
private Log logger;
private java.util.Map<String, ShipperInterface> shipperInterfaceMap;
public OrderProcessorImpl(Log lgr, java.util.Map<String, ShipperInterface> siMap) {
if (null == lgr) {
throw new IllegalArgumentException("Log is null");
}
if (null == siMap) {
throw new IllegalArgumentException("Map<String, ShipperInterface> is null");
}
this.logger = lgr;
this.shipperInterfaceMap = siMap;
}
public void ProcessOrder(String preferredShipperAbbreviation, Order ord) {
this.logger.info(String.format("About to ship. (%1s)", preferredShipperAbbreviation));
ShipperInterface foundShipperInterface = this.FindShipperInterface(preferredShipperAbbreviation);
foundShipperInterface.ShipOrder(ord);
}
private ShipperInterface FindShipperInterface(String friendlyName)
{
ShipperInterface returnItem = null;
if (null != this.shipperInterfaceMap)
{
returnItem = this.shipperInterfaceMap.entrySet().stream()
.filter(e -> e.getKey().equalsIgnoreCase(friendlyName))
.map(Map.Entry::getValue)
.findFirst()
.orElse(null);
}
if (null == returnItem)
{
throw new NullPointerException(String.format("shipperProviderMap did not contain expected item. (Key='%s')", friendlyName));
}
return returnItem;
}
}
and "main" method
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
BeanFactory factory = context;
Order ord = new Order();
OrderProcessorInterface opi = context.getBean(OrderProcessorImpl.class);
opi.ProcessOrder("fedexFriendlyName", ord);
Something like this should work. This uses @Autowired and not xml configuration:
@org.springframework.stereotype.Service
public class OrderProcessorImpl implements OrderProcessorInterface {
private List<ShipperInterface> shipperProviders;
private Map<String, ShipperInterface> shipperProvidersMap = new HashMap<>();
@Autowired
public void setShipperProviders(List<ShipperInterface> shipperProviders) {
this.shipperProviders= shipperProviders;
this.shipperProviders.stream().forEach(p->shipperProvidersMap .put(/* your code for getting the key */, p));
}
Gradle dependency hint:
compile group: 'org.springframework', name: 'spring-context', version: '5.1.9.RELEASE'