SpringBoot根據(jù)注解動(dòng)態(tài)執(zhí)行類中的方法實(shí)現(xiàn)
1、需求
有一個(gè)接口提供了xx的服務(wù),有兩個(gè)場景分別實(shí)現(xiàn)了xx的具體邏輯,標(biāo)記為xx1和xx2。
然后場景一過來的時(shí)候執(zhí)行xx1邏輯,場景二過來的時(shí)候執(zhí)行xx2邏輯。
2、簡單實(shí)現(xiàn)
定義一個(gè)service層,提供xx的接口。
然后定義兩個(gè)serviceImpl,@Service(name="")標(biāo)記不同的名稱,分別提供xx的具體實(shí)現(xiàn)。
在使用時(shí),通過@Resource(name="")注入兩個(gè)組件。
接著硬編碼,當(dāng)場景一時(shí)調(diào)用組件1的xx方法,當(dāng)場景二時(shí)調(diào)用組件2的xx方法。
這種方法可讀性較高,邏輯也清晰,但是擴(kuò)展性不高,硬編碼的硬傷。
3、通過自定義注解的方式
(1)實(shí)現(xiàn)方案
首先,構(gòu)造一個(gè)自定義注解@Extension,用于存放場景所需的信息。
其次,定義一個(gè)Service接口提供xx服務(wù)
然后,定義兩個(gè)ServiceImpl類實(shí)現(xiàn)接口的xx服務(wù),并且標(biāo)記@Service注解。同時(shí)新增@Extension注解,輸入場景信息。
接著,定義一個(gè)@PostConstruct方法,在方法中讀取容器中所有帶@Extension注解的示例,將注解的場景信息作為key,示例作為Object放入某個(gè)組件ExtRespository的Map中存起來。
最后,請求過來時(shí)解析場景信息,從ExtRespository的Map中讀取實(shí)例信息,通過Function<T,R>函數(shù)式編程調(diào)用接口的xx方法。
(2)實(shí)現(xiàn)示例
1)Extension.java
自定義注解接口
/** * 自定義注解 */ @Retention(RetentionPolicy.RUNTIME) // 作用于運(yùn)行時(shí) @Target(ElementType.TYPE) // 作用于類上 @Component public @interface Extension { String bizScene() default "defaultBizScene"; String useCase() default "defaultUseCase"; }
2)Father.java
模擬Service接口
public interface Father { public String sayHello(); }
3)FatherOne.java
模擬ServiceImpl實(shí)現(xiàn)類1
@Component @Extension(bizScene="test", useCase="one") public class FatherOne implements Father { @Override public String sayHello() { System.out.println("測試: father1"); return "father1"; } }
4)FatherTwo.java
模擬ServiceImpl實(shí)現(xiàn)類2
@Component @Extension(bizScene="test", useCase="two") public class FatherTwo implements Father{ @Override public String sayHello() { System.out.println("測試: father2"); return "father2"; } }
5)ExtInitiator.java
項(xiàng)目啟動(dòng)時(shí)的一部分初始化
@Component public class ExtInitiator { @Autowired ExtRespository extRespository; @Autowired private ApplicationContext applicationContext; @PostConstruct public void init(){ Map<String, Object> extensionBeans = applicationContext.getBeansWithAnnotation(Extension.class); for(Object bean : extensionBeans.values()){ Class<?> extensionClz = ClassUtils.getUserClass(bean); Extension extension = AnnotationUtils.findAnnotation(extensionClz, Extension.class); String bizScene = extension.bizScene(); String useCase = extension.useCase(); extRespository.getExtRepository().put(bizScene + "_" + useCase, bean); } } }
6)ExtRespository.java
組件提供map的存放
@Component public class ExtRespository { private Map<String, Object> extRepository = new HashMap<>(); public Map<String, Object> getExtRepository(){ return extRepository; } }
7)Test方法中測試
@Autowired ExtRespository extRespository; @Test public void testExtension() { Function<Father, String> exeFunction = extention -> extention.sayHello(); System.out.println("test_two場景下調(diào)用sayHello:" + exeFunction.apply((Father)extRespository.getExtRepository().get("test_two"))); }
運(yùn)行測試方法時(shí)顯示:
測試: father2
test_two場景下調(diào)用sayHello:father2
到此這篇關(guān)于SpringBoot根據(jù)注解動(dòng)態(tài)執(zhí)行類中的方法實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)SpringBoot 動(dòng)態(tài)執(zhí)行類中方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springboot通過SchedulingConfigurer實(shí)現(xiàn)多定時(shí)任務(wù)注冊及動(dòng)態(tài)修改執(zhí)行周期(示例詳解)
- SpringBoot如何動(dòng)態(tài)修改Scheduled(系統(tǒng)啟動(dòng)默認(rèn)執(zhí)行,動(dòng)態(tài)修改)
- 基于Springboot執(zhí)行多個(gè)定時(shí)任務(wù)并動(dòng)態(tài)獲取定時(shí)任務(wù)信息
- 詳解SpringBoot 創(chuàng)建定時(shí)任務(wù)(配合數(shù)據(jù)庫動(dòng)態(tài)執(zhí)行)
相關(guān)文章
- 數(shù)組和二維數(shù)組感覺用王者榮耀的裝備欄來舉例解釋,應(yīng)該更易懂一些。從基礎(chǔ)開始講,后續(xù)會(huì)講到JAVA高級,中間會(huì)穿插面試題和項(xiàng)目實(shí)戰(zhàn),希望能給大家?guī)韼椭?/div> 2022-03-03
SpringBoot使用Jasypt對YML文件配置內(nèi)容加密的方法(數(shù)據(jù)庫密碼加密)
本文介紹了如何在SpringBoot項(xiàng)目中使用Jasypt對application.yml文件中的敏感信息(如數(shù)據(jù)庫密碼)進(jìn)行加密,通過引入Jasypt依賴、配置加密密鑰、加密敏感信息并測試解密功能,可以提高配置文件的安全性,減少因配置文件泄露導(dǎo)致的安全風(fēng)險(xiǎn),感興趣的朋友一起看看吧2025-03-03Java中的System.arraycopy()淺復(fù)制方法詳解
這篇文章主要介紹了Java中的System.arraycopy()淺復(fù)制方法詳解,Java數(shù)組的復(fù)制操作可以分為深度復(fù)制和淺度復(fù)制,簡單來說深度復(fù)制,可以將對象的值和對象的內(nèi)容復(fù)制;淺復(fù)制是指對對象引用的復(fù)制,需要的朋友可以參考下2023-11-11特殊數(shù)據(jù)結(jié)構(gòu)之使用Java實(shí)現(xiàn)單調(diào)棧示例
這篇文章主要為大家介紹了特殊數(shù)據(jù)結(jié)構(gòu)之使用Java實(shí)現(xiàn)單調(diào)棧示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09如何使用CountDownLatch同步j(luò)ava多線程
這篇文章主要介紹了如何使用CountDownLatch同步j(luò)ava多線程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08常用的ResponseEntity.BodyBuilder和自定義ResponseEntity的實(shí)例
這篇文章主要介紹了常用的ResponseEntity.BodyBuilder和自定義ResponseEntity的實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07最新評論