一個接口多個實現類,controller層如何指定特定實現類進行調用?


背景

今天面試一家公司,面試官問了一個問題“在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接口下有兩個實現類InterfaceImpl1InterfaceImpl2
接口:

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;    //正常啟動


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM