摘要:生產(chǎn)環(huán)境由注冊中心,通過調(diào)用,其它環(huán)境直接通過直接通過調(diào)用。當(dāng)然動態(tài)代理提供接口的默認(rèn)實(shí)現(xiàn)只是演示,并沒有什么實(shí)際內(nèi)容。下一篇動態(tài)代理反射注解優(yōu)化代碼二反射
一、背景
在項(xiàng)目中需要調(diào)用外部接口,由于需要調(diào)用不同環(huán)境(生產(chǎn)、測試、開發(fā))的相同接口(例如:向生、測試、開發(fā)環(huán)境的設(shè)備下發(fā)同一個(gè)APP)。
1.生產(chǎn)環(huán)境由SpringCloud注冊中心,通過Feign調(diào)用, 2.其它環(huán)境直接通過OKHttp直接通過Url調(diào)用。
因此需要根據(jù)傳入的環(huán)境調(diào)選擇不同的調(diào)用方式。
優(yōu)化前代碼結(jié)構(gòu)下面以添加和刪除設(shè)備接口為例(一切從簡,不代表真正業(yè)務(wù)代碼):
public interface DeviceHandler { void remoteAddBatch(RemoteAddDeviceParam remoteAddDeviceParam, Integer envValue); void remoteDeleteBatch(Integer envValue, ListsnsList); }
Feign方式實(shí)現(xiàn):
@Component @Slf4j public class DeviceHandlerFeignImpl implements DeviceHandler { @Autowired private DeviceFeignClient deviceFeignClient; @Override public void remoteAddBatch(RemoteAddDeviceParam remoteAddDeviceParam, Integer envValue) { RestResult restResult = deviceFeignClient.create(remoteAddDeviceParam); ... } @Override public void remoteDeleteBatch(Integer envValue, ListsnsList) { RestResult restResult = deviceFeignClient.deleteBySnList(snsList); ... } }
Url方式實(shí)現(xiàn)
@Component @Slf4j public class DeviceHandlerUrlImpl implements DeviceHandler { @Override public void remoteAddBatch(RemoteAddDeviceParam remoteAddDeviceParam, Integer envValue) { String url = getAddUrlByEnvValue(envValue); String response = OkHttpUtils.httpPostSyn(url, JSON.toJSONString(snsList), false); RestResult restResult = JSON.parseObject(response, RestResult.class); ... } @Override public void remoteDeleteBatch(Integer envValue, ListsnsList) { String url = getDelUrlByEnvValue(envValue); String response = OkHttpUtils.httpPostSyn(url, JSON.toJSONString(snsList), false); RestResult restResult = JSON.parseObject(response, RestResult.class); ... } }
起到路由作用的DeviceHandlerRouter(其實(shí)類似代理),選擇具體調(diào)用哪種實(shí)現(xiàn),對上層服務(wù)暴露的是DeviceHandlerRouter。
@Component public class DeviceHandlerRouter implements DeviceHandler { ... @Autowired private DeviceHandlerUrlImpl deviceHandlerUrlImpl; @Autowired private DeviceHandlerUrlImpl deviceHandlerUrlImpl; @Override public void remoteAddBatch(RemoteAddDeviceParam remoteAddDeviceParam, Integer envValue) { getDeviceHandler(envValue).remoteAddBatch(remoteAddDeviceParam,envValue); } @Override public void remoteDeleteBatch(Integer envValue, ListsnsList) { getDeviceHandler(envValue).remoteDeleteBatch(envValue,snsList); } private DeviceHandler getDeviceHandler(Integer envValue) { //根據(jù)傳入的環(huán)境返回DeviceHandlerUrlImpl 或 DeviceHandlerUrlImpl } }
上層服務(wù)調(diào)用 DeviceHandlerRouter 實(shí)現(xiàn)對設(shè)備的添加和刪除操作。
存在問題如果新增一直接口調(diào)用就需要新增實(shí)現(xiàn)xxxRouter,但是代碼基本上都是一樣的。有沒有什么方式不用寫代碼而提供默認(rèn)實(shí)現(xiàn)?
動態(tài)代理提供默認(rèn)實(shí)現(xiàn)@Slf4j public class DynamicProxyBeanFactory implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //各位客官別急,這里只是簡單打印一下,真正的代碼在下一篇 log.info("DynamicProxyBeanFactory------------------>invoke") //正兒八經(jīng)的隨便創(chuàng)建一個(gè)DeviceHandlerUrlImpl return new DeviceHandlerUrlImpl(); } public staticT newMapperProxy(Class mapperInterface) { ClassLoader classLoader = mapperInterface.getClassLoader(); Class>[] interfaces = new Class[]{mapperInterface}; DynamicProxyBeanFactory proxy = new DynamicProxyBeanFactory(); return (T) Proxy.newProxyInstance(classLoader, interfaces, proxy); } }
調(diào)用:
DeviceHandler deviceHandler = DynamicProxyBeanFactory.newMapperProxy(DeviceHandler.class);
deviceHandler.remoteAddBatch(...);
參考鏈接:動態(tài)代理提供接口默認(rèn)實(shí)現(xiàn)
總結(jié)以上我們只是拋出在實(shí)際開發(fā)中面臨的問題,以及找到解決問題的第一步的方法。 當(dāng)然動態(tài)代理提供接口的默認(rèn)實(shí)現(xiàn)只是演示,并沒有什么實(shí)際內(nèi)容。
下一篇:SpringBoot 動態(tài)代理|反射|注解|AOP 優(yōu)化代碼(二)-反射
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/75296.html
摘要:動態(tài)代理反射注解優(yōu)化代碼一動態(tài)代理提供接口默認(rèn)實(shí)現(xiàn)我們拋出問題,并且提出解決問題的第一步的方法。重寫動態(tài)代理類,實(shí)現(xiàn)通過的查找出傳入的所有泛型的實(shí)現(xiàn)下一篇動態(tài)代理反射注解優(yōu)化代碼三注解 SpringBoot 動態(tài)代理|反射|注解|AOP 優(yōu)化代碼(一)-動態(tài)代理提供接口默認(rèn)實(shí)現(xiàn) 我們拋出問題,并且提出解決問題的第一步的方法。下面我們繼續(xù)深入,動態(tài)代理和反射繼續(xù)解決我們的問題。 改動代...
摘要:上一篇動態(tài)代理反射注解優(yōu)化代碼二反射我們實(shí)現(xiàn)了通過反射完善找到目標(biāo)類,然后通過動態(tài)代理提供默認(rèn)實(shí)現(xiàn),本篇我們將使用自定義注解來繼續(xù)優(yōu)化。下一篇動態(tài)代理反射注解四動態(tài)代理對象注入到容器 上一篇SpringBoot 動態(tài)代理|反射|注解|AOP 優(yōu)化代碼(二)-反射 我們實(shí)現(xiàn)了通過反射完善找到目標(biāo)類,然后通過動態(tài)代理提供默認(rèn)實(shí)現(xiàn),本篇我們將使用自定義注解來繼續(xù)優(yōu)化。 創(chuàng)建注解 1.創(chuàng)建枚舉...
摘要:上一篇動態(tài)代理反射注解優(yōu)化代碼三注解本篇我們將實(shí)現(xiàn)通過代理生成的對象注入到容器中。單元測試優(yōu)化代碼待續(xù)參考文章 上一篇:SpringBoot 動態(tài)代理|反射|注解|AOP 優(yōu)化代碼(三)-注解 本篇我們將實(shí)現(xiàn)通過代理生成的對象注入到spring容器中。首先需要實(shí)現(xiàn)BeanDefinitionRegistryPostProcessor, ApplicationContextAware兩個(gè)...
摘要:又是什么其實(shí)就是一種實(shí)現(xiàn)動態(tài)代理的技術(shù),利用了開源包,先將代理對象類的文件加載進(jìn)來,之后通過修改其字節(jié)碼并且生成子類。 在實(shí)際研發(fā)中,Spring是我們經(jīng)常會使用的框架,畢竟它們太火了,也因此Spring相關(guān)的知識點(diǎn)也是面試必問點(diǎn),今天我們就大話Aop。特地在周末推文,因?yàn)樵撈恼麻喿x起來還是比較輕松詼諧的,當(dāng)然了,更主要的是周末的我也在充電學(xué)習(xí),希望有追求的朋友們也盡量不要放過周末時(shí)...
摘要:具體的動態(tài)代理運(yùn)行原理這里暫不展開,網(wǎng)上有很多相關(guān)的內(nèi)容,比如這篇翻譯過來就是面向方面切面編程。所以切面可以理解為和的集合。 1.靜態(tài)代理 在提及動態(tài)代理前先說明一下靜態(tài)代理模式,靜態(tài)代理模式是一種很常見的通用設(shè)計(jì)模式,實(shí)現(xiàn)也很簡單,uml類圖如下: showImg(https://segmentfault.com/img/bVba3gn?w=737&h=312); 如上圖所示,代理類...
閱讀 3288·2021-09-30 09:47
閱讀 2306·2021-09-10 10:51
閱讀 1910·2021-09-08 09:36
閱讀 2939·2019-08-30 12:56
閱讀 3045·2019-08-30 11:16
閱讀 2634·2019-08-29 16:40
閱讀 3005·2019-08-29 15:25
閱讀 1642·2019-08-29 11:02