亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

目錄
@EnableFeignClients" >@EnableFeignClients
@Import()" >@Import()
openfeign中作用" >openfeign中作用
registerDefaultConfiguration(metadata, registry)" >registerDefaultConfiguration(metadata, registry)
registerFeignClients(metadata, registry)" >registerFeignClients(metadata, registry)
首頁 Java java教程 Spring Cloud原始碼分析:第一篇

Spring Cloud原始碼分析:第一篇

Aug 15, 2023 pm 04:04 PM
spring cloud

莫要嘲笑看原始碼的朋友,現(xiàn)在面試只是八股文是靠不住了,更多是問專案問題以及原始碼及問題。我也是逼不得已,不然誰想造輪子,很累人又枯燥!

個人覺得看原始碼的前提是得會用,用熟了可以猜猜別人是怎麼實現(xiàn)的,如果有相關(guān)官方文件那就在看看官方文件。

不過,可惜的是很多官方文件寫得很爛,讓你看了會那種雲(yún)裡霧裡的。

最近我在研究openfeign原始碼的時候,發(fā)現(xiàn)在原始碼中有個關(guān)鍵註解:@Import。

專案啟動類別:

/**
 * @author tianwc  公眾號:java后端技術(shù)全棧、面試專欄
 * @version 1.0.0
 * @date 2023年07月07日 16:47
 * 在線刷題 1200+題和1000+篇干貨文章:<a href="http://woaijava.cc/">博客地址</a>
 */
@EnableFeignClients(basePackages = {"com.tian.feign"})
@SpringBootApplication()
public class    MqApplication {
    public static void main(String[] args) {
        SpringApplication.run(MqApplication.class, args);
    }
}

然後,就是我們的feignclient介面:

/**
 * @author tianwc  公眾號:java后端技術(shù)全棧、面試專欄
 * @version 1.0.0
 * @date 2023年07月07日 16:47
 * 在線刷題 1200+題和1000+篇干貨文章:<a href="http://woaijava.cc/">博客地址</a>
 */
@FeignClient(contextId = "userFeignClient", value = "charge-user-service")
public interface UserFeignClient {

    /**
     * 邀請成功增加收益
     *
     * @param invitedDto 邀請增加收益
     * @return 邀請成功
     */
    @PostMapping("/user/invited/register")
    CommonResult<Boolean> invitedRegister(@RequestBody InvitedDto invitedDto);
}

使用案例:

/**
 * @author tianwc  公眾號:java后端技術(shù)全棧、面試專欄
 * @version 1.0.0
 * @date 2023年07月07日 16:47
 * 在線刷題 1200+題和1000+篇干貨文章:<a href="http://woaijava.cc/">博客地址</a>
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Resource
    UserFeignClient userFeignClient;

    @PostMapping("/invited")
    public CommonResult invitedRegister(){
        //省略不想搞的代碼
        return userFeignClient.invitedRegister(invitedDto);
    }

}

從上面在的程式碼中,我們可以看出openfeign關(guān)鍵程式碼有:

@EnableFeignClients(basePackages = {"com.tian.feign"})

@FeignClient(contextId = "userFeignClient", value = "charge-user-service")

userFeignClient.invitedRegister(invitedDto);

################################################################################################################################。 ##

@EnableFeignClients

@EnableFeignClients這個注解在啟動類上,我們肯定要重點關(guān)注。

小技巧:凡是以@Enable開頭的各種注解基本上都是開啟xxxx。比如:@EnableFeignClients表示開啟feign客戶端。

我們進入@EnableFeignClients

/**
 * @author tianwc  公眾號:java后端技術(shù)全棧、面試專欄
 * @version 1.0.0
 * @date 2023年07月07日 16:47
 * 在線刷題 1200+題和1000+篇干貨文章:<a href="http://woaijava.cc/">博客地址</a>
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(FeignClientsRegistrar.class)
public @interface EnableFeignClients { 
 String[] value() default {}; 
 String[] basePackages() default {}; 
 Class<?>[] basePackageClasses() default {}; 
 Class<?>[] defaultConfiguration() default {}; 
 Class<?>[] clients() default {};
}

我們通常只需要關(guān)心屬性basePackages,表示我們需要掃描的包目錄。

如果既沒有指定basePackages,也沒有指定basePackageClasses,則采用啟動類所在的目錄作為包掃描路徑。默認是這種情況。

本文重點來了,在這個注解@EnableFeignClients上有個注解@Import(FeignClientsRegistrar.class),這里到底是有什么作用?

@Import()

#@Import()註解是在spring 3.0版本中引入的,字面意義就是導入.

@Import註解的全類名是org.springframework.context.annotation.Import。其只有一個預設(shè)的value屬性,該屬性類型為Class<?>[],表示可以傳入一個或多個Class物件。

透過註解可以看出,該註解有如下作用:

可以導入一個或多個元件類別(通常是@Configuration配置類別)該註解的功能與Spring XML中的<import/>元素相同??梢詫?code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">@Configuration配置類別、ImportSelectImportBeanDefinitionRegistrar的實作類別。

從spring 4.2版本開始,也可以引用常規(guī)元件類別(普通類別),該功能類似於AnnotationConfigApplicationContext.register()方法。

此註解可以在類別中聲明,也可以在元註解中聲明。如果需要匯入XML或其他非@Configuration定義的資源,可以使用@ImportResource註解。

通常有三種使用方式:

  • @Import一個普通類 spring會將該類加載到spring容器中
  • @Import一個類,該類實現(xiàn)了ImportBeanDefinitionRegistrar接口,在重寫的registerBeanDefinitions方法里面,能拿到BeanDefinitionRegistry的注冊器,能手工往beanDefinitionMap中注冊 beanDefinition
  • @Import一個類 該類實現(xiàn)了ImportSelector 重寫selectImports方法該方法返回了String[]數(shù)組的對象,數(shù)組里面的類都會注入到spring容器當中。

下面我們來聊聊@Import在openfeign的這里是起到什么作用。

openfeign中作用

回答上面的代碼里

@Import(FeignClientsRegistrar.class)

這里導入的是FeignClientsRegistrar類,我們再來看看他的類關(guān)系圖:

Spring Cloud原始碼分析:第一篇

從類關(guān)系圖來看,FeignClientsRegistrar實現(xiàn)了ImportBeanDefinitionRegistrar接口。再結(jié)合@Import的三種使用方式中的第二種方式,能手工往beanDefinitionMap中注冊 beanDefinition。

/**
 * @author tianwc  公眾號:java后端技術(shù)全棧、面試專欄
 * @version 1.0.0
 * @date 2023年07月07日 16:47
 * 在線刷題 1200+題和1000+篇干貨文章:<a href="http://woaijava.cc/">博客地址</a>
 */
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata,
                                    BeanDefinitionRegistry registry) {
    registerDefaultConfiguration(metadata, registry);
    registerFeignClients(metadata, registry);
}

這個方法registerBeanDefinitions()是feign的核心入口方法,其中會做兩件事:

注冊默認的配置和注冊所有的FeignClient。

registerDefaultConfiguration(metadata, registry)

這個方法是負責注冊OpenFeign的默認配置 ,邏輯相對簡單:

private void registerDefaultConfiguration(AnnotationMetadata metadata,
                                          BeanDefinitionRegistry registry) {
    //獲取@EnableFeignClients的全部屬性
    //@EnableFeignClients(basePackages = {"com.tian.feign"}) 
    //這里的basePackages就是我們指定的熟悉
    Map<String, Object> defaultAttrs = metadata
        .getAnnotationAttributes(EnableFeignClients.class.getName(), true);

    if (defaultAttrs != null && defaultAttrs.containsKey("defaultConfiguration")) {
        String name;
        if (metadata.hasEnclosingClass()) {
            name = "default." + metadata.getEnclosingClassName();
        }
        else {
            name = "default." + metadata.getClassName();
        }
        registerClientConfiguration(registry, name,
                                    defaultAttrs.get("defaultConfiguration"));
    }
}

defaultAttrs中內(nèi)容如下:

Spring Cloud原始碼分析:第一篇

但是這里我們只關(guān)注defaultConfiguration,我們并有對其進行設(shè)置,所以我們可以忽略他。重點是下面這個方法。

registerFeignClients(metadata, registry)

這里就是項目啟動時和openfeign相關(guān)的核心代碼,這也是@EnableFeignClients@FeignClient兩個注解關(guān)聯(lián)起來的地方。

我們進入源碼中:

public void registerFeignClients(AnnotationMetadata metadata,
                                 BeanDefinitionRegistry registry) {
    
    ClassPathScanningCandidateComponentProvider scanner = getScanner();
    scanner.setResourceLoader(this.resourceLoader);

    Set<String> basePackages;

    Map<String, Object> attrs = metadata
        .getAnnotationAttributes(EnableFeignClients.class.getName());
    AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter(
        FeignClient.class);
    final Class<?>[] clients = attrs == null ? null
        : (Class<?>[]) attrs.get("clients");
    if (clients == null || clients.length == 0) {
        scanner.addIncludeFilter(annotationTypeFilter);
        basePackages = getBasePackages(metadata);
    }
    else {
        final Set<String> clientClasses = new HashSet<>();
        basePackages = new HashSet<>();
        for (Class<?> clazz : clients) {
            basePackages.add(ClassUtils.getPackageName(clazz));
            clientClasses.add(clazz.getCanonicalName());
        }
        AbstractClassTestingTypeFilter filter = new AbstractClassTestingTypeFilter() {
            @Override
            protected boolean match(ClassMetadata metadata) {
                String cleaned = metadata.getClassName().replaceAll("\\$", ".");
                return clientClasses.contains(cleaned);
            }
        };
        scanner.addIncludeFilter(
            new AllTypeFilter(Arrays.asList(filter, annotationTypeFilter)));
    }

    for (String basePackage : basePackages) {
        Set<BeanDefinition> candidateComponents = scanner
            .findCandidateComponents(basePackage);
        for (BeanDefinition candidateComponent : candidateComponents) {
            if (candidateComponent instanceof AnnotatedBeanDefinition) {
                // verify annotated class is an interface
                AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition) candidateComponent;
                AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();
                Assert.isTrue(annotationMetadata.isInterface(),
                              "@FeignClient can only be specified on an interface");

                Map<String, Object> attributes = annotationMetadata
                    .getAnnotationAttributes(
                    FeignClient.class.getCanonicalName());

                String name = getClientName(attributes);
                registerClientConfiguration(registry, name,
                                            attributes.get("configuration"));

                registerFeignClient(registry, annotationMetadata, attributes);
            }
        }
    }
}

代碼一行一行看是不是覺得很累,我給你總結(jié)好了。

上面的方法分為以下七個步驟:

  • 首先取得@EnableFeignClients註解的所有屬性,主要為了拿到掃描套件路徑(basePackages);
  • #因為一般不會在@EnableFeignClients註解中配置clients屬性,所以會進入到clients屬性為空時的邏輯;
  • ##然後透過
    getScanner()方法獲取掃描器:ClassPathScanningCandidateComponentProvider,並將上下文AnnotationConfigServletWebServerApplicationContext作為掃描器的ResourceLoader
  • 接著給掃描器
    ClassPathScanningCandidateComponentProvider新增一個註解過濾器(AnnotationTypeFilter),只過濾出包含@FeignClient註解的BeanDefinition;
    ;
  • #;
    ##再透過getBasePackages(metadata)
    方法取得
  • @EnableFeingClients###註解中的指定的套件掃描路徑或掃描類別;如果沒有取得到,則預設(shè)掃描啟動類別所在的套件路徑;######
  • 然後進入到核心邏輯:透過scanner.findCandidateComponents(basePackage)方法從套件路徑下掃描出所有標註了@FeignClient註解並符合條件組裝的介面;
  • 最後將FeignClientConfigurationBeanDefinitionRegistry中註冊一下,再對FeignClient做真正的註冊操作。

總結(jié)

openfeign原始碼中的@Import註解在這裡的作用就是將掃描到帶有FeignClient註解的全部介面類別以bean的形式註冊到spring IOC容器中。

再來強調(diào)@Import註解使用方式:

  • @Import一個普通類別spring會將該類別載入到spring容器中
  • @Import一個類,該類別實作了ImportBeanDefinitionRegistrar接口,在重寫的registerBeanDefinitions方法裡面,能拿到BeanDefinitionRegistry的註冊器,可以手工往 beanDefinitionMap中註冊beanDefinition
  • #@Import一個類別該類別實作了ImportSelector 重寫selectImports方法此方法傳回了String[]陣列的對象,陣列裡面的類別都會注入到spring容器當中。

好了,今天就分享這麼多。這個openfeign裡面還有很多很有意思的地方,我們下次再分享吧!

以上是Spring Cloud原始碼分析:第一篇的詳細內(nèi)容。更多資訊請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願投稿,版權(quán)歸原作者所有。本站不承擔相應的法律責任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請聯(lián)絡admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動的應用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Laravel 教程
1597
29
PHP教程
1488
72
巧用Spring Cloud解決微服務架構(gòu)下的負載平衡問題 巧用Spring Cloud解決微服務架構(gòu)下的負載平衡問題 Jun 23, 2023 pm 01:40 PM

隨著企業(yè)應用的複雜度不斷增加,越來越多的企業(yè)開始將應用程式拆分為多個微服務,透過微服務之間的協(xié)作完成整個業(yè)務流程。這種架構(gòu)方式能夠使應用程式更加穩(wěn)定、擴展性更強,但同時也帶來了一些新的問題,例如負載平衡,服務發(fā)現(xiàn)等。本文將介紹如何透過SpringCloud來解決微服務架構(gòu)下的負載平衡問題。什麼是負載平衡?負載平衡(LoadBalancing)是指在多個伺服器、網(wǎng)

Spring Cloud原始碼分析:第一篇 Spring Cloud原始碼分析:第一篇 Aug 15, 2023 pm 04:04 PM

個人覺得看原始碼的前提是得會用,用熟了可以猜猜別人是怎麼實現(xiàn)的,如果有相關(guān)官方文件那就在看看官方文件。

Spring Cloud微服務架構(gòu)部署與維 Spring Cloud微服務架構(gòu)部署與維 Jun 23, 2023 am 08:19 AM

隨著網(wǎng)路的快速發(fā)展,企業(yè)級應用的複雜度日益增加。針對這種情況,微服務架構(gòu)應運而生。它以模組化、獨立部署、可擴展性高等特點,成為當今企業(yè)級應用開發(fā)的首選。作為一種優(yōu)秀的微服務架構(gòu),SpringCloud在實際應用中展現(xiàn)了極大的優(yōu)勢。本文將介紹SpringCloud微服務架構(gòu)的部署與維運。一、部署SpringCloud微服務架構(gòu)SpringCloud

面向服務的Spring Cloud微服務開發(fā) 面向服務的Spring Cloud微服務開發(fā) Jun 23, 2023 pm 12:30 PM

隨著網(wǎng)路的發(fā)展和科技的不斷更新,傳統(tǒng)的單體應用已經(jīng)無法滿足使用者需求,微服務的概念應運而生。 SpringCloud是一個由Pivotal公司推出的微服務開發(fā)工具包,它為開發(fā)人員提供了一種極為方便的方式來建置、部署和管理微服務架構(gòu)應用程式。本文將對服務導向的SpringCloud微服務開發(fā)進行詳細介紹,包括SpringCloud的概念與架構(gòu)、微服務開發(fā)流程以

Java語言中的Spring Cloud框架介紹 Java語言中的Spring Cloud框架介紹 Jun 09, 2023 pm 10:54 PM

Java語言中的SpringCloud框架介紹隨著雲(yún)端運算和微服務的流行,SpringCloud框架成為了Java語言中建構(gòu)雲(yún)端原生應用的首選框架之一。本文將介紹SpringCloud框架的概念與特點,以及如何使用SpringCloud建構(gòu)微服務架構(gòu)。 SpringCloud簡介SpringCloud框架是基於SpringBoot的微服務框架。它為

如何使用Java開發(fā)一個基於Spring Cloud Kubernetes的容器編排應用 如何使用Java開發(fā)一個基於Spring Cloud Kubernetes的容器編排應用 Sep 20, 2023 am 11:15 AM

如何使用Java開發(fā)一個基於SpringCloudKubernetes的容器編排應用隨著容器技術(shù)的發(fā)展和廣泛應用,容器編排工具也成為了開發(fā)人員不可或缺的一部分。 Kubernetes作為目前最受歡迎的容器編排工具之一,已經(jīng)成為了業(yè)界的標準。在此背景下,結(jié)合SpringCloud和Kubernetes,我們可以很方便地開發(fā)出基於容器編排的應用程式。本文將詳細介紹

實現(xiàn)分散式鎖的Spring Cloud微服務實踐 實現(xiàn)分散式鎖的Spring Cloud微服務實踐 Jun 22, 2023 pm 11:28 PM

隨著微服務架構(gòu)的流行,越來越多的企業(yè)開發(fā)團隊開始使用SpringCloud建立自己的微服務系統(tǒng)。在分散式環(huán)境下,實現(xiàn)分散式鎖是一項重要的技術(shù)挑戰(zhàn)。本文將介紹在SpringCloud框架下,如何實現(xiàn)分散式鎖定的微服務實踐。首先,我們要了解什麼是分散式鎖。分散式鎖是一種用於保護共享資源的存取的技術(shù),它可以保證在分散式環(huán)境下多個節(jié)點不會同時對相同資源進行修改或

Spring Cloud微服務架構(gòu)下的監(jiān)控與警告實踐 Spring Cloud微服務架構(gòu)下的監(jiān)控與警告實踐 Jun 22, 2023 pm 03:04 PM

隨著微服務架構(gòu)的廣泛應用,如何有效地監(jiān)控和警告成為了開發(fā)人員和維運人員面臨的問題之一。本文將重點放在SpringCloud微服務架構(gòu)下實踐監(jiān)控和警告的具體方法。一、監(jiān)控指標的選擇在進行監(jiān)控前,首先需要確定需要監(jiān)控的指標。常見的指標包括:CPU使用率、記憶體使用率、網(wǎng)路頻寬、磁碟空間、HTTP請求的回應時間、服務呼叫的次數(shù)和延遲等。這些指標可透過各種監(jiān)控工

See all articles