Java獲取接口的所有實(shí)現(xiàn)類方法總結(jié)示例
業(yè)務(wù)開發(fā)中,有時(shí)需要獲取到某個(gè)接口或抽象類的所有實(shí)現(xiàn)方法,然后再某個(gè)類中集中進(jìn)行處理,都有哪些方法呢?
一、 如果是普通的Java應(yīng)用,可以使用JDK自帶的一個(gè)類加載器ServiceLoader,其實(shí)就是SPI機(jī)制。
ServiceLoaderloader = ServiceLoader.load(IWork.class);
因?yàn)樵赟erviceLoader.load的時(shí)候,是根據(jù)傳入的接口類,遍歷META-INF/services目錄下的以該類命名的文件中的所有類,并實(shí)例化返回。所以,不適用于抽象類。
二、如果在Springboot工程中,接口的實(shí)現(xiàn)可以由IOC容器來托管,就可以非常簡單的從Spring容器中獲取到實(shí)現(xiàn)類集合。具體包括2種渠道。
直接使用Spring注解@Autowired
實(shí)現(xiàn)ApplicationContextAware接口獲取并管理所有實(shí)現(xiàn)類。 就可以很簡單的利用@Autowired來獲取到實(shí)現(xiàn)類的list或map集合。
三、Springboot具體實(shí)現(xiàn)實(shí)例講解
1)接口類
IWorkService.java
public interface IWorkService {
String workPlace();
}
2)實(shí)現(xiàn)類
TeacherWorkService.java
@Service
public class TeacherWorkService implements IWorkService {
@Override
public String workPlace() {
return "school";
}
}
DoctorWorkService.java
@Service
public class DoctorWorkService implements IWorkService{
@Override
public String workPlace() {
return "hospital";
}
}
3)Aware實(shí)現(xiàn)類
WorkServiceLocator.java
@Component
public class WorkServiceLocator implements ApplicationContextAware {
//手動(dòng)獲取,key是bean的name,value是實(shí)現(xiàn)類
private Map<String, IWorkService> workServiceMap;
//手動(dòng)獲取,list是所有的實(shí)現(xiàn)類
private List<IWorkService> workServiceList;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
workServiceMap = applicationContext.getBeansOfType(IWorkService.class);
workServiceList = new ArrayList<>(workServiceMap.values());
}
public Map<String, IWorkService> getAllMap() {
return workServiceMap;
}
public IWorkService getByName(String beanName) {
return workServiceMap.get(beanName);
}
public List<IWorkService> getAllList() {
return workServiceList;
}
}
3)Test入口類
@SpringBootTest(classes = {Application.class})
@RunWith(SpringRunner.class)
public class WorkServiceTest {
/**
* 方式1:直接使用spring依賴注入注解
*/
@Autowired
private Map<String, IWorkService> workServiceMap;
/**
* 方式2:直接使用spring的依賴注入注解
*/
@Autowired
private List<IWorkService> workServiceList;
/**
* 方式3:借助spring的ApplicationContextAware
*/
@Autowired
private WorkServiceLocator workServiceLocator;
@Test
public void testAll() {
Map<String, IWorkService> allMap = workServiceLocator.getAllMap();
List<IWorkService> allList = workServiceLocator.getAllList();
IWorkService iWorkService = workServiceLocator.getByName("teacherWorkService");
}
}
四、總結(jié)
對于普通的Java工程實(shí)現(xiàn)獲取接口所有實(shí)現(xiàn)類需要借助SPI機(jī)制,且僅限于接口;對于Spring工程,則有@Autowired自動(dòng)獲取和實(shí)現(xiàn)ApplicationContextAware手動(dòng)獲取2種,既支持接口實(shí)現(xiàn)類、也支持抽象類的實(shí)現(xiàn)類。
附:java獲取實(shí)現(xiàn)某個(gè)接口的所有實(shí)現(xiàn)類集合
關(guān)鍵在于: applicationContext.getBeansOfType(ChartService.class);
獲得Map對象的key為實(shí)現(xiàn)類的名稱如:chartSimpleServiceImpl
獲得Map對象的value為實(shí)現(xiàn)類對象如: com.read.data.cms.service.impl.ChartExtraServiceImpl@5c85b6e9
applicationContext的獲取方法有很多種,我這里暫列兩種
第一種方式實(shí)現(xiàn)接口所有類集合(注解)
@Autowire
private ApplicationContext applicationContext;
Map<String,ChartService> res = applicationContext.getBeansOfType(ChartService.class);
res.get("實(shí)現(xiàn)類的字符串如:chartSimpleServiceImpl")
res.get獲得的結(jié)果,就是當(dāng)前實(shí)現(xiàn)類對象第二種方式實(shí)現(xiàn)接口所有類集合(實(shí)現(xiàn)接口)
/**
* @author: tianyong
* @Time: 2019/6/26 11:17
* @description:服務(wù)工廠(主要用于動(dòng)態(tài)注入接口實(shí)現(xiàn)類)
*/
@Component
public class ServiceFactory implements ApplicationContextAware {
//定義成員變量
private static Map<String,ChartService> res;
/**
* @author: tianyong
* @time: 2019/6/27 16:04
* @description:設(shè)置上下文參數(shù)
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
res = applicationContext.getBeansOfType(ChartService.class);
}
/**
* @author: tianyong
* @time: 2019/6/27 16:05
* @description:根據(jù)標(biāo)記返回當(dāng)前接口實(shí)現(xiàn)類
*/
public static <T extends ChartService> T getServices(String flag){
return (T)res.get(flag);
}
}到此這篇關(guān)于Java獲取接口的所有實(shí)現(xiàn)類方法的文章就介紹到這了,更多相關(guān)Java獲取接口所有實(shí)現(xiàn)類內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot3中Spring?WebFlux?SSE服務(wù)器發(fā)送事件的實(shí)現(xiàn)步驟
本文介紹了如何使用SpringBoot3和響應(yīng)式編程實(shí)現(xiàn)服務(wù)器發(fā)送事件(SSE),并討論了其在實(shí)時(shí)數(shù)據(jù)推送場景中的優(yōu)勢,通過示例代碼,展示了如何創(chuàng)建SSE控制器、客戶端接收數(shù)據(jù)以及優(yōu)化與擴(kuò)展,感興趣的朋友跟隨小編一起看看吧2024-11-11
在IDEA中如何設(shè)置最多顯示文件標(biāo)簽個(gè)數(shù)
在使用IDEA進(jìn)行編程時(shí),可能會(huì)同時(shí)打開多個(gè)文件,當(dāng)文件過多時(shí),文件標(biāo)簽會(huì)占據(jù)大部分的IDEA界面,影響我們的編程效率,因此,我們可以通過設(shè)置IDEA的文件標(biāo)簽顯示個(gè)數(shù),來優(yōu)化我們的編程環(huán)境,具體的設(shè)置方法如下2024-10-10
IDEA2020.1同步系統(tǒng)設(shè)置到GitHub的方法
這篇文章主要介紹了IDEA2020.1同步系統(tǒng)設(shè)置到GitHub的方法,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05
Java多線程并發(fā)生產(chǎn)者消費(fèi)者設(shè)計(jì)模式實(shí)例解析
這篇文章主要介紹了Java多線程并發(fā)生產(chǎn)者消費(fèi)者設(shè)計(jì)模式實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
Spring Security實(shí)現(xiàn)5次密碼錯(cuò)誤觸發(fā)賬號(hào)自動(dòng)鎖定功能
在現(xiàn)代互聯(lián)網(wǎng)應(yīng)用中,賬號(hào)安全是重中之重,然而,暴力 破解攻擊依然是最常見的安全威脅之一,攻擊者通過自動(dòng)化腳本嘗試大量的用戶名和密碼組合,試圖找到漏洞進(jìn)入系統(tǒng),所以為了解決這一問題,賬號(hào)鎖定機(jī)制被廣泛應(yīng)用,本文介紹了Spring Security實(shí)現(xiàn)5次密碼錯(cuò)誤觸發(fā)賬號(hào)鎖定功能2024-12-12
JavaWeb基礎(chǔ)概念以及與架構(gòu)之間有哪些區(qū)別
JavaWeb是基于Java技術(shù)棧開發(fā)的Web應(yīng)用,SpringMVC是實(shí)現(xiàn)JavaWeb的一種框架,C/S架構(gòu)和B/S架構(gòu)的區(qū)別主要在客戶端形式、開發(fā)維護(hù)成本、響應(yīng)速度和跨平臺(tái)能力,本文介紹JavaWeb基礎(chǔ)概念以及與架構(gòu)之間有哪些區(qū)別,感興趣的朋友跟隨小編一起看看吧2025-12-12

