1. 程式人生 > >【記錄】spring中一個介面多個實現類

【記錄】spring中一個介面多個實現類

重構遇到個小問題,記錄下:

錯誤資訊:

***************************
APPLICATION FAILED TO START
***************************

Description:

Field xxxService in com.alibaba.xxx required a single bean, but 2 were found:

解決方法:

Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

程式碼案例:

import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

/**
 * 一個介面
 */
public interface DataTransferService {
    Long transferData() throws Exception;

}

/**
 * 實現類一
 * 重要:新增@Primary標記為預設初始化的類
 */
@Component("dataTransferService")
@Primary
class DataTransferServiceImpl implements DataTransferService {

    @Override
    public Long transferData() throws Exception {
        return 0L;
    }
}

/**
 *實現類二
 */
@Component("dataTransferServiceSync")
class DataTransferServiceSyncImpl implements DataTransferService {

    @Override
    public Long transferData() throws Exception {

        return 0L;
    }
}

使用方式:

/**
 * 兩種使用方式,已測試
 */
public class ActivityDemo {
    /**方式一*/
    @Autowired
    @Qualifier("dataTransferService")
    protected DataTransferService dataTransferService;

    @Autowired
    @Qualifier("dataTransferServiceSync")
    protected DataTransferService dataTransferServiceSync;

    /**方式二*/

//    @Resource("dataTransferService")
//    protected DataTransferService dataTransferService;
//
//    @Resource("dataTransferServiceSync")
//    protected DataTransferService dataTransferServiceSync;
}

注意:新增@Primary告訴spring初始化時使用哪個主要的實現類。

補充:https://baijiahao.baidu.com/s?id=1608114169828948852&wfr=spider&for=pc

@Autowired與@Resource的區別

(1)@Autowired

@Autowired為Spring提供的註解,需要匯入包org.springframework.beans.factory.annotation.Autowired;只按照byType注入。

@Autowired註解是按照型別(byType)裝配依賴物件,預設情況下它要求依賴物件必須存在,如果允許null值,可以設定它的required屬性為false。如果我們想使用按照名稱(byName)來裝配,可以結合@Qualifier註解一起使用。如下:

(2)@Resource

@Resource預設按照ByName自動注入,由J2EE提供,需要匯入包javax.annotation.Resource。@Resource有兩個重要的屬性:name和type,而Spring將@Resource註解的name屬性解析為bean的名字,而type屬性則解析為bean的型別。

所以,如果使用name屬性,則使用byName的自動注入策略,而使用type屬性時則使用byType自動注入策略。如果既不制定name也不制定type屬性,這時將通過反射機制使用byName自動注入策略。