需求描述:當一個接口有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"); } }