摘要:動(dòng)態(tài)代理反射注解優(yōu)化代碼一動(dòng)態(tài)代理提供接口默認(rèn)實(shí)現(xiàn)我們拋出問(wèn)題,并且提出解決問(wèn)題的第一步的方法。重寫(xiě)動(dòng)態(tài)代理類,實(shí)現(xiàn)通過(guò)的查找出傳入的所有泛型的實(shí)現(xiàn)下一篇?jiǎng)討B(tài)代理反射注解優(yōu)化代碼三注解
SpringBoot 動(dòng)態(tài)代理|反射|注解|AOP 優(yōu)化代碼(一)-動(dòng)態(tài)代理提供接口默認(rèn)實(shí)現(xiàn) 我們拋出問(wèn)題,并且提出解決問(wèn)題的第一步的方法。下面我們繼續(xù)深入,動(dòng)態(tài)代理和反射繼續(xù)解決我們的問(wèn)題。
改動(dòng)代碼結(jié)構(gòu)新增一個(gè)HandlerRougter接口,其目的就是替代上一篇的DeviceHandlerRouter
public interface HandlerRouter{ T getHandler(Integer env,Object... args); }
其中T是具體的業(yè)務(wù)接口。下面實(shí)現(xiàn)DeviceHandler的HandlerRouter:
public interface DeviceHandlerRouter extends HandlerRouter{ }
那么上層代碼的調(diào)用方式將會(huì)類似下面的代碼:
DeviceHandlerRouter deviceHandlerRouter = ... deviceHandlerRouter.getHandler(...). remoteAddBatch(...)反射+動(dòng)態(tài)代理
前面說(shuō)過(guò),每增加一種接口調(diào)用,就需要重新實(shí)現(xiàn)xxxHandlerRouter,那么下面我們通過(guò)動(dòng)態(tài)代理和反射提供DeviceHandler的默認(rèn)實(shí)現(xiàn)。
1.通過(guò)反射獲取HandlerRouter
首先加入下面的依賴
org.reflections reflections 0.9.10
/** * 通過(guò)反射掃描出所有HandlerRouter的子類 * @return */ private Set> getHandlerRouterClasses() { Reflections reflections = new Reflections( "package.name.*", new TypeAnnotationsScanner(),//注解掃描,本節(jié)用不到 new SubTypesScanner() ); return reflections.getSubTypesOf(HandlerRouter.class); }
Set> classes = getHandlerRouterClasses(); //獲取HandlerRouter的子接口的泛型Class 例如:DeviceHandlerRouter接口的DeviceHandler for (Class> clazz : classes) { //clazz 對(duì)應(yīng)DeviceHandlerRouter.class Type[] types = clazz.getGenericInterfaces(); ParameterizedType type = (ParameterizedType) types[0]; //typeName對(duì)應(yīng)DeviceHandlerRouter extends HandlerRouter 中的DeviceHandler.class String typeName = type.getActualTypeArguments()[0].getTypeName(); }
2.SpringBoot ApplicationContext 獲取注入的bean
修改上一篇中實(shí)現(xiàn)的動(dòng)態(tài)代理類,我們想要實(shí)現(xiàn):“能夠根據(jù)傳入的泛型的Class 獲取到Spring容器中該類型的所有bean”,因此我們就需要傳入ApplicationContext。那就需要實(shí)現(xiàn)ApplicationContextAware接口,下面的代碼來(lái)自網(wǎng)絡(luò)。
@Component public class SpringUtil implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringUtil.applicationContext = applicationContext; } public static ApplicationContext getApplicationContext() { return applicationContext; } /** * 通過(guò)class獲取所有該類型的bean * @param clazz * @return */ public static MapgetBeans(Class> clazz) { return getApplicationContext().getBeansOfType(clazz); } }
3.重新實(shí)現(xiàn)動(dòng)態(tài)代理類
@Slf4j public class DynamicProxyBeanFactory implements InvocationHandler { private String className; public DynamicProxyBeanFactory(String className) { this.className = className; @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //獲取實(shí)現(xiàn)className類的所有bean MapclassMap =SpringUtil.getBeans(Class.forName(className)); log.info("DynamicProxyBeanFactory className:{} impl class:{}",className,classMap); //這里先隨便返回一個(gè) return classMap.get("deviceHandlerUrlImpl"); } public static T newMapperProxy(String typeName,Class mapperInterface) { ClassLoader classLoader = mapperInterface.getClassLoader(); Class>[] interfaces = new Class[]{mapperInterface}; DynamicProxyBeanFactory proxy = new DynamicProxyBeanFactory(typeName); return (T) Proxy.newProxyInstance(classLoader, interfaces, proxy); } }
調(diào)用:
Set> classes = getHandlerRouterClasses(); //獲取HandlerRouter的子接口的泛型Class 例如:DeviceHandlerRouter接口的DeviceHandler for (Class> clazz : classes) { //clazz 對(duì)應(yīng)DeviceHandlerRouter.class //clazz 對(duì)應(yīng)DeviceHandlerRouter.class //clazz 對(duì)應(yīng)DeviceHandlerRouter.class Type[] types = clazz.getGenericInterfaces(); ParameterizedType type = (ParameterizedType) types[0]; //typeName對(duì)應(yīng)DeviceHandlerRouter extends HandlerRouter 中的DeviceHandler.class //typeName對(duì)應(yīng)DeviceHandlerRouter extends HandlerRouter 中的DeviceHandler.class //typeName對(duì)應(yīng)DeviceHandlerRouter extends HandlerRouter 中的DeviceHandler.class String typeName = type.getActualTypeArguments()[0].getTypeName(); DeviceHandler deviceHandler = DynamicProxyBeanFactory.newMapperProxy(typeName,clazz); }
總結(jié):這篇文章我們
1.通過(guò)反射獲取了HandlerRouter的所有子接口(這里是DeviceHandlerRouter),以及子接口對(duì)應(yīng)的泛型。
2.重寫(xiě)動(dòng)態(tài)代理類,實(shí)現(xiàn)通過(guò)Spring的ApplicationContext查找出傳入的所有泛型的實(shí)現(xiàn)bean
下一篇:SpringBoot 動(dòng)態(tài)代理|反射|注解|AOP 優(yōu)化代碼(三)-注解
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/75288.html
摘要:上一篇?jiǎng)討B(tài)代理反射注解優(yōu)化代碼二反射我們實(shí)現(xiàn)了通過(guò)反射完善找到目標(biāo)類,然后通過(guò)動(dòng)態(tài)代理提供默認(rèn)實(shí)現(xiàn),本篇我們將使用自定義注解來(lái)繼續(xù)優(yōu)化。下一篇?jiǎng)討B(tài)代理反射注解四動(dòng)態(tài)代理對(duì)象注入到容器 上一篇SpringBoot 動(dòng)態(tài)代理|反射|注解|AOP 優(yōu)化代碼(二)-反射 我們實(shí)現(xiàn)了通過(guò)反射完善找到目標(biāo)類,然后通過(guò)動(dòng)態(tài)代理提供默認(rèn)實(shí)現(xiàn),本篇我們將使用自定義注解來(lái)繼續(xù)優(yōu)化。 創(chuàng)建注解 1.創(chuàng)建枚舉...
摘要:生產(chǎn)環(huán)境由注冊(cè)中心,通過(guò)調(diào)用,其它環(huán)境直接通過(guò)直接通過(guò)調(diào)用。當(dāng)然動(dòng)態(tài)代理提供接口的默認(rèn)實(shí)現(xiàn)只是演示,并沒(méi)有什么實(shí)際內(nèi)容。下一篇?jiǎng)討B(tài)代理反射注解優(yōu)化代碼二反射 一、背景 在項(xiàng)目中需要調(diào)用外部接口,由于需要調(diào)用不同環(huán)境(生產(chǎn)、測(cè)試、開(kāi)發(fā))的相同接口(例如:向生、測(cè)試、開(kāi)發(fā)環(huán)境的設(shè)備下發(fā)同一個(gè)APP)。 1.生產(chǎn)環(huán)境由SpringCloud注冊(cè)中心,通過(guò)Feign調(diào)用, 2.其它環(huán)境直接通過(guò)...
摘要:上一篇?jiǎng)討B(tài)代理反射注解優(yōu)化代碼三注解本篇我們將實(shí)現(xiàn)通過(guò)代理生成的對(duì)象注入到容器中。單元測(cè)試優(yōu)化代碼待續(xù)參考文章 上一篇:SpringBoot 動(dòng)態(tài)代理|反射|注解|AOP 優(yōu)化代碼(三)-注解 本篇我們將實(shí)現(xiàn)通過(guò)代理生成的對(duì)象注入到spring容器中。首先需要實(shí)現(xiàn)BeanDefinitionRegistryPostProcessor, ApplicationContextAware兩個(gè)...
摘要:總結(jié)動(dòng)態(tài)代理的相關(guān)原理已經(jīng)講解完畢,接下來(lái)讓我們回答以下幾個(gè)思考題。 【干貨點(diǎn)】 此處是【好好面試】系列文的第12篇文章。文章目標(biāo)主要是通過(guò)原理剖析的方式解答Aop動(dòng)態(tài)代理的面試熱點(diǎn)問(wèn)題,通過(guò)一步步提出問(wèn)題和了解原理的方式,我們可以記得更深更牢,進(jìn)而解決被面試官卡住喉嚨的情況。問(wèn)題如下 SpringBoot默認(rèn)代理類型是什么 為什么不用靜態(tài)代理 JDK動(dòng)態(tài)代理原理 CGLIB動(dòng)態(tài)代理...
閱讀 3538·2023-04-25 22:44
閱讀 1070·2021-11-15 11:37
閱讀 1721·2019-08-30 15:55
閱讀 2728·2019-08-30 15:54
閱讀 1177·2019-08-30 13:45
閱讀 1506·2019-08-29 17:14
閱讀 1964·2019-08-29 13:50
閱讀 3611·2019-08-26 11:39