国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

手寫Openfeign實現(xiàn)原理——極簡版

這篇具有很好參考價值的文章主要介紹了手寫Openfeign實現(xiàn)原理——極簡版。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前言

最近開發(fā)cloud項目,里面涉及到服務(wù)間調(diào)用,最后使用的openfeign解決的,于是對于openfeign的底層原理有些興趣了,提前透露一下底層無非就是使用一些http調(diào)用的工具幫助我們實現(xiàn)了請求調(diào)用

Openfeign實現(xiàn)思路

手寫Openfeign實現(xiàn)原理——極簡版,java,spring,spring boot,spring cloud,openfeign

前期準備

基本依賴項

  • 首先創(chuàng)建一個springboot項目
  • 有一個發(fā)送請求的工具這里使用的ribbon
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
            <version>2.2.9.RELEASE</version>
            <scope>compile</scope>
            <optional>true</optional>
        </dependency>

開始實現(xiàn)

自定義注解

創(chuàng)建兩個自定義注解,分別用于在啟動類和接口上添加

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Configuration
@Import(OpenInstantiationAwareBeanPostProcessor.class)//這個類重點注意
public @interface EnableRemoteClient {
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface CustomProxy {
    String servie();

    String address();
}

自定義代理類

代理類中有一個RestTemplate 用于發(fā)送請求

public class CustomProxyHandler implements InvocationHandler {
    RestTemplate restTemplate=new RestTemplate();

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        //首先獲取對象
        Class<?> declaringClass = method.getDeclaringClass();
        //判斷當前的被代理對象是否使用了自定的注解
        if(declaringClass.isAnnotationPresent(CustomProxy.class)){
            CustomProxy annotation = declaringClass.getAnnotation(CustomProxy.class);
            String servie = annotation.servie();
            String address = annotation.address();
            String url=address+servie;
            RequestMapping annotation1 = method.getAnnotation(RequestMapping.class);
            url=url+annotation1.value()[0];
            //判斷請求方法是否入?yún)?/span>
            if(args!=null&&args.length!=0){
                return restTemplate.getForObject(url,method.getReturnType(),args);
            }else {
                return restTemplate.getForObject(url,method.getReturnType());
            }
        }else{
            return null;
        }


    }
}

定義創(chuàng)建代理對象的工廠

用于創(chuàng)建代理對象使用,

public class ProxyFactory {

    /**
     * @description: 創(chuàng)建具體的代理對象
     * @author: 
     * @date: 2023/9/1 17:30
     * @param: [targetInterface]
     * @return: T
     **/
    public static  <T> T createProxy(Class<T> targetInterface) {
        return (T) Proxy.newProxyInstance(
                targetInterface.getClassLoader(),
                new Class[]{targetInterface},
                new CustomProxyHandler()
        );
    }
}

InstantiationAwareBeanPostProcessor實現(xiàn)bean的注入

InstantiationAwareBeanPostProcessor 是 Spring 框架提供的一個擴展接口,它在 Spring 容器實例化 bean 之前和之后對 bean 進行處理。其主要功能如下:

  1. 實例化前置處理(Before Instantiation):在 Spring 容器實例化 bean 之前,可以通過這個接口來自定義 bean 的實例化方式。可以在此處進行一些特殊的準備工作,比如使用自定義的實例化邏輯或者切入點的選擇。

  2. 實例化后置處理(After Instantiation):在 Spring 容器實例化 bean 之后,可以通過這個接口對實例化后的 bean 進行處理。可以在此處做一些初始化的操作,比如對屬性進行賦值、調(diào)用初始化方法等。

  3. 屬性設(shè)置前置處理(Before Property Set):在 Spring 容器對 bean 的屬性進行設(shè)置之前,可以通過這個接口來自定義屬性的設(shè)置方式。可以在此處對屬性進行修改或者校驗操作。

  4. 屬性設(shè)置后置處理(After Property Set):在 Spring 容器對 bean 的屬性進行設(shè)置之后,可以通過這個接口對屬性設(shè)置后的 bean 進行處理??梢栽诖颂幾鲆恍傩栽O(shè)置后的額外操作。

  5. 初始化前置處理(Before Initialization):在 Spring 容器對 bean 進行初始化之前,可以通過這個接口來自定義初始化的方式??梢栽诖颂幪砑右恍╊~外的初始化邏輯。

  6. 初始化后置處理(After Initialization):在 Spring 容器對 bean 進行初始化之后,可以通過這個接口對初始化后的 bean 進行處理??梢栽诖颂幾鲆恍┏跏蓟蟮念~外操作。

通過實現(xiàn) InstantiationAwareBeanPostProcessor 接口,并重寫其中的方法,可以在 Spring 容器實例化和初始化 bean 的各個階段進行自定義處理,從而靈活地對 bean 進行定制化的操作。

OpenInstantiationAwareBeanPostProcessor 自定義

public class OpenInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor, ApplicationContextAware {


    private ApplicationContext applicationContext;
    /**
     * 實例化前,后面的方法可以不用看了
     * @param beanClass
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {

        log.info("正在為:{}生成代理對象,被代理的類為:{}",beanName,beanClass.getName());
        if(!beanClass.isAnnotationPresent(CustomProxy.class)){
            return null;
        }

        //動態(tài)代理里面需要實現(xiàn)的方法,本文采用的是jdk動態(tài)代理
        //返回代理對象
        Object object = ProxyFactory.createProxy(beanClass);
        return object;

    }

    /**
     * 實例化后
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        return true;
    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        return pvs;
    }


    /**
     * 初始化錢
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    /**
     * 初始化后
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext=applicationContext;
    }
}

feign接口

這里的servie沒有參數(shù)是因為我的另一個服務(wù)中沒有配置context-path,如果你們自己的被調(diào)用的那個demo中有配置一定要加上哦

@CustomProxy(servie = "",address = "http://localhost:8082/")
public interface MyService {
    @RequestMapping(value = "/QuerySubselect",method = RequestMethod.GET)
    String  test();
}

啟動類

@SpringBootApplication
@EnableRemoteClient
@Import({MyService.class})//接口注冊,注意接口上面加@Se
public class OpenfeignDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(OpenfeignDemoApplication.class, args);
    }
    
}

小結(jié)

這個版本的實現(xiàn)目前spring還不能識別我添加了注解的這個接口,需要在啟動類中使用@Import注解手動配置,所以還不完善,不過后期會繼續(xù)完善的,目前博主也在學習這個,這個思路就是基于我們正常的發(fā)送請求,然后有一個人幫助我們?nèi)グl(fā)送請求這個思路。

踩坑記錄

@Import

將接口 MyService 標識為 @Import 的目的是為了在啟動類中將該接口的實現(xiàn)類(動態(tài)代理對象)注冊到 Spring 容器中。

當你使用 @Import({MyService.class}) 注解時,Spring 在啟動時會掃描被注解的類,并根據(jù)其類型進行相應的處理。在這種情況下,MyService 類型是一個接口,而不是一個具體的類。

由于接口無法直接實例化,因此你需要在某處提供對 MyService 接口的實現(xiàn)類的創(chuàng)建邏輯。通常情況下,使用動態(tài)代理是一種常見的方式。

動態(tài)代理是一種在運行時生成代理類的機制,可以在不修改原始接口源代碼的情況下,通過代理類來增強接口的功能。你可以編寫一個動態(tài)代理類,實現(xiàn) MyService 接口,并在動態(tài)代理類中實現(xiàn)你所需的增強邏輯。

然后,在啟動類上使用 @Import 注解,并傳入該動態(tài)代理類的類型,告訴 Spring 在啟動時需要將該動態(tài)代理類注冊到容器中。

這樣,當其他組件需要使用 MyService 接口時,Spring 容器會從容器中獲取該接口的實例,而實際上獲得的是動態(tài)代理對象,該代理對象會在實際調(diào)用接口方法時根據(jù)你的增強邏輯進行處理。

  • 因為openfeign的標注的接口沒有實現(xiàn)類所以需要這個@Import注解幫助我們告訴spring容器可以去容器中去這個類型的代理對象,目前還沒有想到其他的方式不用使用@Import注解聲明的。后續(xù)再想想辦法

@Component和@Configuration區(qū)別是什么

@Configuration 注解不能直接添加到接口上,因為 @Configuration 注解是用于標識一個類為配置類的注解,它主要用于定義和配置 Bean 對象以及其他的配置信息。
手寫Openfeign實現(xiàn)原理——極簡版,java,spring,spring boot,spring cloud,openfeign
一開始使用這個注解導致使用了自定義注解的接口一直掃描不到,后來修改為@Component注解后就可以了。
@Component 是 Spring Framework 中的一個核心注解之一,用于將一個普通的 Java 類標識為一個可以被 Spring 自動掃描并管理的組件。

具體來說,@Component 注解可以應用于以下場景:

  1. Bean 的自動掃描和注冊:通過在類上添加 @Component 注解,Spring 容器會自動掃描并將該類作為 Bean 進行注冊,使得我們可以通過依賴注入等方式方便地使用該類的實例。

  2. 類型指定的自動裝配:當需要進行自動裝配時,Spring 容器會檢測所有被 @Component 注解標記的類,并根據(jù)類型進行自動裝配。

@Component 注解是一個通用的注解,如果對應的類有更具體的角色或作用,還可以使用其他派生注解,例如:

  • @Controller:標識一個類是控制器(Controller)組件,用于接收和處理用戶請求。
  • @Service:標識一個類是服務(wù)(Service)組件,用于封裝業(yè)務(wù)邏輯。
  • @Repository:標識一個類是數(shù)據(jù)訪問倉庫(Repository)組件,用于訪問持久化數(shù)據(jù)。

這些派生注解都是基于 @Component 注解的,繼承了 @Component 的功能,并且更明確地表示了對應類的角色和用途。

總結(jié)

對于這次去實現(xiàn)這么一個框架的小demo自己思考了一天,不能說很長時間吧,主要是因為對于spring中提供的一些擴展機制還不是很了解,但是我相信它一定提供了能夠解決我上面問題的一些api的,只是我還沒有發(fā)現(xiàn)而已。對于這些技術(shù)的應用底層原理還是很簡單的,可以發(fā)現(xiàn)無非就是沒讓你做的事情有人幫你做了這么一個過程,只不過這個過程被人封裝起來以后就是一個技術(shù)或者一個框架了。文章來源地址http://www.zghlxwxcb.cn/news/detail-688762.html

到了這里,關(guān)于手寫Openfeign實現(xiàn)原理——極簡版的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 如何在Spring Boot中使用OpenFeign,這一篇足夠了。

    第一章 如何在Spring Boot中使用OpenFeign,這一篇足夠了。 第二章 OpenFeign修改默認通訊協(xié)議Https 第三章 OpenFeign默認通訊方式修改成OkHttp,包含F(xiàn)eignConfigruation自定義、OkHttp客戶端自定義詳細配置介紹 OpenFeign是一個聲明式、模板化的HTTP客戶端,可以幫助我們更加便捷地編寫基于H

    2024年02月07日
    瀏覽(47)
  • Docker實踐:使用Docker搭建個人開發(fā)環(huán)境(極簡版)

    本文是在服務(wù)器 已經(jīng)配置好 Docker 相關(guān)環(huán)境的情況下, 簡要介紹 了在服務(wù)器上如何構(gòu)建 Docker 鏡像來搭建個人開發(fā)環(huán)境,因此本文 不涉及 Docker 的安裝、維護以及各種細節(jié),若要 詳細了解 ,請查看文章最后的 相關(guān)資料 一節(jié)。 以下所有操作均在同一文件夾(例如 /media/user

    2024年02月16日
    瀏覽(21)
  • openGauss學習筆記-03 openGauss極簡版單節(jié)點安裝

    openGauss學習筆記-03 openGauss極簡版單節(jié)點安裝

    openGauss支持以腳本方式進行極簡安裝,極簡安裝包括單節(jié)點安裝和一主一備節(jié)點安裝。 3.1 獲取安裝包 3.1.1 下載對應平臺的安裝包 從openGauss開源社區(qū)下載對應平臺的安裝包 登錄openGauss開源社區(qū),選擇對應平臺的最新安裝包下載。對于個人開發(fā)者或非企業(yè)級環(huán)境,下載極簡安

    2024年02月13日
    瀏覽(43)
  • 如何用python連接mysql和mongodb數(shù)據(jù)庫【極簡版】

    前些天發(fā)現(xiàn)了一個巨牛的人工智能學習網(wǎng)站,通俗易懂,風趣幽默,忍不住分享一下給大家?!緦毑厝肟凇?。 為了鞏固所學的知識,作者嘗試著開始發(fā)布一些學習筆記類的博客,方便日后回顧。當然,如果能幫到一些萌新進行新技術(shù)的學習那也是極好的。作者菜菜一枚,文章

    2024年01月23日
    瀏覽(25)
  • C#搭建Socket服務(wù)器與客戶端,助你快速入門(極簡版)

    C#搭建Socket服務(wù)器與客戶端,助你快速入門(極簡版)

    一、服務(wù)器的搭建 新建一個C#控制臺應用,用于搭建服務(wù)器。 注:serverManager除了接收消息,也可以發(fā)送消息?;境吮O(jiān)聽,其他活它都干。 二、客戶端的搭建 再建一個C#控制臺應用,用于搭建客戶端。 搭建好之后,先運行服務(wù)器端, 再運行客戶端。 一個簡單的服務(wù)器和

    2024年02月09日
    瀏覽(99)
  • 基于react18+vite4+arco.design搭建極簡版后臺管理模板

    基于react18+vite4+arco.design搭建極簡版后臺管理模板

    趁著國慶前夕整了一個 vite4 結(jié)合 react18 搭建后臺管理模板,搭配上字節(jié)團隊react組件庫 ArcoDesign ,整體操作功能非常絲滑。目前功能 支持多種模板布局、暗黑/亮色模式、國際化、權(quán)限驗證、多級路由菜單、tabview標簽欄快捷菜單、全屏控制 等功能。極簡非凡的布局界面、高定

    2024年02月08日
    瀏覽(23)
  • 個性化定制界面 VS 極簡版原裝界面:你更喜歡哪一個?為什么?

    個性化定制界面 VS 極簡版原裝界面:你更喜歡哪一個?為什么?

    不管昨天、今天、明天,能豁然開朗就是最美好的一天。 個性化定制界面和極簡版原裝界面,哪一個你用起來更加順手呢,相比之下你更喜歡哪一個? 隨著移動互聯(lián)網(wǎng)技術(shù)的不斷發(fā)展,手機和電腦成為我們生活中必不可少的工具之一。而手機和電腦界面作為我們與手機交互

    2024年02月11日
    瀏覽(26)
  • 【Spring Boot】SpringBoot參數(shù)驗證以及實現(xiàn)原理

    【Spring Boot】SpringBoot參數(shù)驗證以及實現(xiàn)原理

    參數(shù)驗證很重要,是平時開發(fā)環(huán)節(jié)中不可少的一部分,但是我想很多后端同事會偷懶,干脆不做,這樣很可能給系統(tǒng)的穩(wěn)定性和安全性帶來嚴重的危害。 那么在Spring Boot應用中如何做好參數(shù)校驗工作呢,本文提供了小技巧以及驗證實現(xiàn)原理,你知道幾個呢? Spring Boot 提供了內(nèi)

    2023年04月16日
    瀏覽(39)
  • 用Spring Boot輕松實現(xiàn)定時任務(wù)--原理詳解

    ??在現(xiàn)代化的web開發(fā)中,定時任務(wù)是一個非常常見的功能。Spring Boot為我們提供了一個簡便的方式來處理這些任務(wù),我們只需加入一些注解和配置即可完成。本文將介紹 Spring Boot 定時任務(wù)的基本概念和原理,以及如何在具體業(yè)務(wù)場景中使用和優(yōu)化配置。 ??定時任務(wù)是指在

    2024年02月06日
    瀏覽(28)
  • Spring Boot源碼解讀與原理剖析:深入探索Java開發(fā)的奧秘!

    Spring Boot源碼解讀與原理剖析:深入探索Java開發(fā)的奧秘!

    關(guān)注+點贊+評論,評論區(qū)回復“Spring Boot源碼解讀與原理剖析:深入探索Java開發(fā)的奧秘!” 每篇最多 評論3條 ?。〔捎贸楠勚肿詣永≡u論區(qū)有效評論送書兩本, 開獎時間:9月11號 承載著作者的厚望,掘金爆火小冊同名讀物 《Spring Boot源碼解讀與原理剖析》 正式出書!

    2024年02月10日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包