背景
今天面試一家公司,面試官問了一個問題“在Service層一個接口有多個實現類,那么在controller層如何指定某個實現類進行調用呢?”,給我問懵了,因為之前做項目沒有遇到過這種情況,都是一個接口對應一個實現類。
如接口為:
public interface BuyerService {
//查詢訂單詳情
OrderDTO getOrderOne(String openid,String orderId);
//取消訂單
OrderDTO cancelOrder(String openid,String orderId);
}
對應的實現類為:
public class BuyerServiceImpl implements BuyerService {
@Override
public OrderDTO getOrderOne(String openid, String orderId) {
return checkOrderOwner(openid,orderId);
}
@Override
public OrderDTO cancelOrder(String openid, String orderId) {
OrderDTO orderDTO = checkOrderOwner(openid,orderId);
if(orderDTO == null){
log.error("【取消訂單】 查不到該訂單,orderId={}",orderId);
throw new SellException(ResultEnum.ORDER_NOT_EXIST);
}
return orderService.cancel(orderDTO);
}
}

如果一個接口有多個實現類,在Controller層注入后調用,怎么知道調用的是接口的哪個方法呢?
經過一番測試,和查找資料,終於找到了結果。
一個接口對應多個實現類
一個接口對應對個實現類,需要注入指定的實現類。
如:Interface接口下有兩個實現類InterfaceImpl1和InterfaceImpl2。
接口:
package com.example.service;
public interface Interface1 {
void fun1();
}
對應實現類1InterfaceImpl1:
@Service("s1")
public class Interface1Impl1 implements Interface1 {
@Override
public void fun1() {
System.out.println("接口1實現類 ...");
}
public void fun2(){
System.out.println("接口1實現類1 fun2 ...");
}
}
對應實現類2InterfaceImpl2:
@Service("s2")
public class Interface1Impl2 implements Interface1 {
@Override
public void fun1() {
System.out.println("接口1實現類 ...");
}
public void fun2(){
System.out.println("接口1實現類2 fun2 ...");
}
}
解決方法
指明實現類的優先級
在寫實現類的時候事先指明實現類的優先級,注入的時候就會使用優先級高的實現類。在controller中注入接口,默認使用的是Primary 標注的實現類的方法
如:
@Service("s1")
@Primary //**同一個接口的多個實現類,最多只能有一個添加該注解**
public class InterfaceImpl1 implements Interface {
。。。
}
通過 @Autowired 和 @Qualifier 配合注入
@Autowired
@Qualifier("interface1Impl1")
Interface1 interface1; //正常啟動
使用@Resource注入,根據默認類名區分
@Resource(name = "interface1Impl1")
Interface1 interface1; //正常啟動
使用@Resource注入,根據@Service指定的名稱區分
@Resource(name = "s1")
Interface1 interface1; //正常啟動
