国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

SpringBoot 動(dòng)態(tài)代理|反射|注解|AOP 優(yōu)化代碼(三)-注解

Charles / 2800人閱讀

摘要:上一篇?jiǎng)討B(tài)代理反射注解優(yōu)化代碼二反射我們實(shí)現(xiàn)了通過反射完善找到目標(biāo)類,然后通過動(dòng)態(tài)代理提供默認(rèn)實(shí)現(xiàn),本篇我們將使用自定義注解來繼續(xù)優(yōu)化。下一篇?jiǎng)討B(tài)代理反射注解四動(dòng)態(tài)代理對象注入到容器

上一篇SpringBoot 動(dòng)態(tài)代理|反射|注解|AOP 優(yōu)化代碼(二)-反射

我們實(shí)現(xiàn)了通過反射完善找到目標(biāo)類,然后通過動(dòng)態(tài)代理提供默認(rèn)實(shí)現(xiàn),本篇我們將使用自定義注解來繼續(xù)優(yōu)化。

創(chuàng)建注解

1.創(chuàng)建枚舉 ClientType,用來標(biāo)明Handler的實(shí)現(xiàn)方式

public enum ClientType {
    FEIGN,URL
}

2.創(chuàng)建注解ApiClient,用來標(biāo)明Handler的實(shí)現(xiàn)方式

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ApiClient {
    ClientType type();
}

3.創(chuàng)建HandlerRouterAutoImpl注解,來標(biāo)記該HandlerRouter是否通過代理提供默認(rèn)實(shí)現(xiàn)

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface HandlerRouterAutoImpl {
   /**
    * 在spring容器中對應(yīng)的名稱
    * @return
    */
   String name();
}

4.DeviceHandlerRouter添加注解,以動(dòng)態(tài)代理提供默認(rèn)實(shí)現(xiàn)

@HandlerRouterAutoImpl(name = "deviceHandlerRouter")
public interface DeviceHandlerRouter extends HandlerRouter {
}

5.DeviceHandlerFeignImpl、DeviceHandlerUrlImpl 添加注解標(biāo)明具體的實(shí)現(xiàn)方式

@ApiClient(type = ClientType.FEIGN)
@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, List snsList) {   
        RestResult restResult = deviceFeignClient.deleteBySnList(snsList);      
        ... 
    }   
  
}
@ApiClient(type = ClientType.URL)
@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, List snsList) {
        String url = getDelUrlByEnvValue(envValue);
        String response = OkHttpUtils.httpPostSyn(url, JSON.toJSONString(snsList), false);
        RestResult restResult = JSON.parseObject(response, RestResult.class);
        ...
    }
}

6.通過注解掃描目標(biāo)類

掃描HandlerRouterAutoImpl注解的類,通過動(dòng)態(tài)代理提供默認(rèn)的實(shí)現(xiàn)

    /**
     * 通過反射掃描出所有使用注解HandlerRouterAutoImpl的類
     * @return
     */
    private Set> getAutoImplClasses() {
        Reflections reflections = new Reflections(
                "io.ubt.iot.devicemanager.impl.handler.*",
                new TypeAnnotationsScanner(),
                new SubTypesScanner()
        );
        return reflections.getTypesAnnotatedWith(HandlerRouterAutoImpl.class);
    }

動(dòng)態(tài)代理類中,獲取業(yè)務(wù)接口的實(shí)現(xiàn)類,并獲取ApiClient注解,然后分類,保存到Map中。以在調(diào)用getHandler方式時(shí)根據(jù)傳入的環(huán)境值,返回不同實(shí)現(xiàn)方式的實(shí)例。

@Slf4j
public class DynamicProxyBeanFactory implements InvocationHandler {
    private String className;
    private Map clientMap = new HashMap<>(2);

    public DynamicProxyBeanFactory(String className) {
        this.className = className;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //獲取過一次后不再獲取
        if (clientMap.size() == 0) {
            initClientMap();
        }
        
        //如果傳入的參數(shù)是1,就返回通過Feign方式實(shí)現(xiàn)的類 (該邏輯只是用來舉例)
        Integer env = (Integer) args[0];
        return 1 == env.intValue() ? clientMap.get(ClientType.FEIGN) : clientMap.get(ClientType.URL);
    }

    private void initClientMap() throws ClassNotFoundException {
        //獲取classStr 接口的所有實(shí)現(xiàn)類
        Map classMap =SpringUtil.getBeansOfType(Class.forName(className));
        log.info("DynamicProxyBeanFactory className:{} impl class:{}",className,classMap);

        for (Map.Entry entry : classMap.entrySet()) {
            //根據(jù)ApiClientType注解將實(shí)現(xiàn)類分為Feign和Url兩種類型
            ApiClient apiClient = entry.getValue().getClass().getAnnotation(ApiClient.class);
            if (apiClient == null) {
                continue;
            }
            clientMap.put(apiClient.type(), entry.getValue());
        }
        log.info("DynamicProxyBeanFactory clientMap:{}",clientMap);
    }


    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);
    }
}

以上我們通過注解、動(dòng)態(tài)代理、反射就實(shí)現(xiàn)了通過注解,找到需要提供默認(rèn)實(shí)現(xiàn)的HandlerRouter子類,并通過動(dòng)態(tài)代理提供默認(rèn)實(shí)現(xiàn)。
還有一個(gè)問題:通過代理生成的對象,該怎么管理,我們并不想通過代碼,手動(dòng)管理。如果能把動(dòng)態(tài)代理生成的對象交給spring容器管理,其它代碼直接自動(dòng)注入就可以了。

下一篇:SpringBoot 動(dòng)態(tài)代理|反射|注解(四)- 動(dòng)態(tài)代理對象注入到Spring容器

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/75283.html

相關(guān)文章

  • SpringBoot 動(dòng)態(tài)代理|反射|注解|AOP 優(yōu)化代碼(二)-反射

    摘要:動(dòng)態(tài)代理反射注解優(yōu)化代碼一動(dòng)態(tài)代理提供接口默認(rèn)實(shí)現(xiàn)我們拋出問題,并且提出解決問題的第一步的方法。重寫動(dòng)態(tài)代理類,實(shí)現(xiàn)通過的查找出傳入的所有泛型的實(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) 我們拋出問題,并且提出解決問題的第一步的方法。下面我們繼續(xù)深入,動(dòng)態(tài)代理和反射繼續(xù)解決我們的問題。 改動(dòng)代...

    spacewander 評論0 收藏0
  • SpringBoot 動(dòng)態(tài)代理|反射|注解|AOP 優(yōu)化代碼(一)-動(dòng)態(tài)代理提供接口默認(rèn)實(shí)現(xiàn)

    摘要:生產(chǎn)環(huán)境由注冊中心,通過調(diào)用,其它環(huán)境直接通過直接通過調(diào)用。當(dāng)然動(dòng)態(tài)代理提供接口的默認(rèn)實(shí)現(xiàn)只是演示,并沒有什么實(shí)際內(nèi)容。下一篇?jiǎng)討B(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)境直接通過...

    mj 評論0 收藏0
  • SpringBoot 動(dòng)態(tài)代理|反射|注解(四)- 動(dòng)態(tài)代理對象注入到Spring容器

    摘要:上一篇?jiǎng)討B(tài)代理反射注解優(yōu)化代碼三注解本篇我們將實(shí)現(xiàn)通過代理生成的對象注入到容器中。單元測試優(yōu)化代碼待續(xù)參考文章 上一篇:SpringBoot 動(dòng)態(tài)代理|反射|注解|AOP 優(yōu)化代碼(三)-注解 本篇我們將實(shí)現(xiàn)通過代理生成的對象注入到spring容器中。首先需要實(shí)現(xiàn)BeanDefinitionRegistryPostProcessor, ApplicationContextAware兩個(gè)...

    lingdududu 評論0 收藏0
  • 學(xué)Aop?看這篇文章就夠了?。。?/b>

    摘要:又是什么其實(shí)就是一種實(shí)現(xiàn)動(dòng)態(tài)代理的技術(shù),利用了開源包,先將代理對象類的文件加載進(jìn)來,之后通過修改其字節(jié)碼并且生成子類。 在實(shí)際研發(fā)中,Spring是我們經(jīng)常會(huì)使用的框架,畢竟它們太火了,也因此Spring相關(guān)的知識點(diǎn)也是面試必問點(diǎn),今天我們就大話Aop。特地在周末推文,因?yàn)樵撈恼麻喿x起來還是比較輕松詼諧的,當(dāng)然了,更主要的是周末的我也在充電學(xué)習(xí),希望有追求的朋友們也盡量不要放過周末時(shí)...

    boredream 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<