springboot如何獲取接口下所有實現(xiàn)類
springboot獲取接口下所有實現(xiàn)類
首先定義一個接口
public interface LoginUserService {
/**
* 判斷手機(jī)號是否允許登錄
*
* @param phone 手機(jī)號
* @return 是否允許
*/
boolean hasUser(String phone) throws ServiceException;
/**
* 通過Phone獲取用戶信息
*
* @param phone 手機(jī)號
* @return 用戶信息
*/
UserDTO getUserInfoByPhone(String phone) throws LoginException;
}
編寫實現(xiàn)類,三個

在這點我的登陸接口上繼承了LoginUserService

在運(yùn)行時需要通過查找bean,但是又不知道具體需要使用哪個bean,在這里自定義一個注解來標(biāo)記使用哪個實現(xiàn)類
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface OrgainzationType {
LoginTypeEnum value();
}在實現(xiàn)類上標(biāo)記具體類型

通過service使用bean進(jìn)行查詢想要的實現(xiàn)類
@Slf4j
@Service
public class LoginServiceImpl implements LoginService, InitializingBean, ApplicationContextAware {
private ApplicationContext applicationContext;
protected Map<LoginTypeEnum, LoginUserService> serviceMap = new HashMap<>();
@Override
public void afterPropertiesSet() throws Exception {
// 查找所有LoginUserService接口的實現(xiàn)類
Map<String, LoginUserService> beanMap = applicationContext.getBeansOfType(LoginUserService.class);
for (LoginUserService impl : beanMap.values()) {
// 獲取注解上的類型
OrgainzationType annotation = AnnotationUtils.findAnnotation(impl.getClass(),OrgainzationType.class);
// 如果沒有添加注解則不需要使用
if (Objects.isNull(annotation)) {
continue;
}
serviceMap.put(annotation.value(), impl);
}
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}運(yùn)行時的類

springboot動態(tài)調(diào)用實現(xiàn)類
因為項目需要,我們有一個功能的接口UserReader。其他的類都是實現(xiàn)這個接口。那么會有多個實現(xiàn)UserReader接口的實現(xiàn)類。現(xiàn)在需要在程序 中動態(tài)的去調(diào)用不通實現(xiàn)類中的方法getUser()。
下面既是功能實現(xiàn)代碼:
1、添加接口
package com.example.mavenceshi.service;
/**
?* @author by CLP
?* @Classname UserReader
?* @Description
?* @Date 2020/9/8 15:16
?*/
public interface UserReader {
? ? String getUser();
}2、創(chuàng)建實現(xiàn)類
1)實現(xiàn)類UserReaderImpl1
package com.example.mavenceshi.service.impl;
import com.example.mavenceshi.service.UserReader;
import org.springframework.stereotype.Component;
/**
?* @author by CLP
?* @Classname UserReader1
?* @Description
?* @Date 2020/9/8 15:17
?*/
@Component
public class UserReaderImpl1 implements UserReader {
? ? @Override
? ? public String getUser() {
? ? ? ? ? ?return "訪問的UserReaderImpl1";
? ? }
}2)實現(xiàn)類 UserReaderImpl2
package com.example.mavenceshi.service.impl;
import com.example.mavenceshi.service.UserReader;
import org.springframework.stereotype.Component;
/**
?* @author by CLP
?* @Classname UserReaderImpl2
?* @Description
?* @Date 2020/9/8 15:18
?*/
@Component
public class UserReaderImpl2 implements UserReader {
? ? @Override
? ? public String getUser() {
? ? ? ? ? return "訪問的UserReaderImpl2";
? ? }
}3、獲取實現(xiàn)類的相關(guān)接口
package com.example.mavenceshi.config;
import com.example.mavenceshi.service.UserReader;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
* @author by CLP
* @Classname BeanConfig
* @Description
* @Date 2020/9/8 15:28
*/
@Component
public class BeanConfig implements InitializingBean, ApplicationContextAware {
private Map<String, UserReader> queryServiceImplMap = new HashMap<>();
private ApplicationContext applicationContext;
public UserReader createQueryService(String type) {
UserReader userReader = queryServiceImplMap.get(type);
if (userReader == null) {
return queryServiceImplMap.get("UserReader1Impl");
}
return userReader;
}
@Override
public void afterPropertiesSet() throws Exception {
Map<String, UserReader> beanMap = applicationContext.getBeansOfType(UserReader.class);
//遍歷該接口的所有實現(xiàn),將其放入map中
for (UserReader serviceImpl : beanMap.values()) {
queryServiceImplMap.put(serviceImpl.getClass().getSimpleName(), serviceImpl);
}
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring中的底層架構(gòu)核心概念類型轉(zhuǎn)換器詳解
這篇文章主要介紹了Spring中的底層架構(gòu)核心概念類型轉(zhuǎn)換器詳解,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-12-12
java?for循環(huán)內(nèi)執(zhí)行多線程問題
這篇文章主要介紹了java?for循環(huán)內(nèi)執(zhí)行多線程問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03
詳解Java ScheduledThreadPoolExecutor的踩坑與解決方法
最近項目上反饋某個重要的定時任務(wù)突然不執(zhí)行了,很頭疼,開發(fā)環(huán)境和測試環(huán)境都沒有出現(xiàn)過這個問題。定時任務(wù)采用的是ScheduledThreadPoolExecutor,后來一看代碼發(fā)現(xiàn)踩了一個大坑。本文就來和大家聊聊這次的踩坑記錄與解決方法,需要的可以參考一下2022-10-10
基于Java實現(xiàn)無向環(huán)和有向環(huán)的檢測
這篇文章主要介紹了如何在?Java?中實現(xiàn)無向環(huán)和有向環(huán)的檢測,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Java有一定的幫助,需要的可以參考一下2022-04-04
Java中關(guān)鍵字final finally finalize的區(qū)別介紹
這篇文章主要給大家分享的是 Java中final,finally,finalize 到底有什么區(qū)別,文章圍繞final,finally,finalize的相關(guān)資料展開詳細(xì)內(nèi)容,具有一定的參考的價值,需要的朋友可以參考一下2022-04-04
Mybatis中的游標(biāo)查詢Cursor(滾動查詢)
這篇文章主要介紹了Mybatis中的游標(biāo)查詢Cursor(滾動查詢),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01

