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)文章
SpringBoot參數(shù)校驗(yàn)Validator框架詳解
Validator框架就是為了解決開發(fā)人員在開發(fā)的時(shí)候少寫代碼,提升開發(fā)效率,Validator專門用來進(jìn)行接口參數(shù)校驗(yàn),今天通過本文給大家介紹SpringBoot參數(shù)校驗(yàn)Validator框架,感興趣的朋友一起看看吧2022-06-06
Java?輸入輸出?IO?NIO?AIO三兄弟對比分析對比分析
這篇文章主要為大家介紹了Java?輸入輸出?IO?NIO?AIO三兄弟對比分析對比分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04

