需求描述:当一个接口有2个以上的实现类时,调用方需要根据参数选择只其中一个实现类
Spring版本:5.1.8.RELEASE
1. 接口和实现类
/**
* 接口
*/
public interface OrderInfoDao { void queryOrderList(); } /** * 实现类A */ @Component public class OrderInfoDaoAImpl implements OrderInfoDao { @Override public void queryOrderList() { System.out.println("Dao A queryOrderList"); } } /** * 实现类B */ @Component public class OrderInfoDaoBImpl implements OrderInfoDao { @Override public void queryOrderList() { System.out.println("Dao B queryOrderList"); } }
现在要求Service层要根据参数输入A或B动态选择实现类。
2. 使用ApplicationContextAware接口实现
@Component
public class OrderInfoServiceImpl implements ApplicationContextAware {
private ApplicationContext applicationContext; public void query(String username){ OrderInfoDao dao = null; if("A".equals(username)){ dao = (OrderInfoDao) applicationContext.getBean("orderInfoDaoAImpl"); } else if("B".equals(username)){ dao = (OrderInfoDao) applicationContext.getBean("orderInfoDaoBImpl"); } dao.queryOrderList(); } /** * ApplicationContextAware接口的实现类,可以拿到上下文 * @param applicationContext * @throws BeansException */ @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } }
3. 使用@Autowired注入Map实现
@Component public class OrderInfoServiceImpl { /** * 用这个方式Spring会在初始化时,自动把OrderInfoDao接口的实现类,全放到Map里 */ @Autowired private Map<String, OrderInfoDao> map; public void query(String username){ // 拼接Dao实现类的名称 String daoName = "orderInfoDao" + username + "Impl"; OrderInfoDao dao = map.get(daoName); if(dao != null){ dao.queryOrderList(); } } }
4. 测试
public class OrderInfo1Test { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); OrderInfoServiceImpl service = context.getBean(OrderInfoServiceImpl.class); service.query("B"); } }