目次
@EnableFeignClients" >@EnableFeignClients
@Import()" >@Import()
openfeign中作用" >openfeign中作用
registerDefaultConfiguration(metadata, registry)" >registerDefaultConfiguration(metadata, registry)
registerFeignClients(metadata, registry)" >registerFeignClients(metadata, registry)
ホームページ Java &#&チュートリアル Spring Cloud のソースコード分析: パート 1

Spring Cloud のソースコード分析: パート 1

Aug 15, 2023 pm 04:04 PM
spring cloud

ソース コードを読んでいる友人を笑わないでください。最近のインタビューは 8 部構成のエッセイ程度であり、信頼性がありません。インタビューでは、プロジェクト、ソース コード、その他の質問をすることが目的です。 。ホイールを作るしかありません。そうしないととても疲れて退屈になってしまいます。

個人的には、ソースコードを読むための前提条件は、それを使用できることであると思います。一度慣れてしまえば、他の人がどのように実装しているかを推測できるようになります。関連する公式があれば、ドキュメントを読んでから公式ドキュメントを読んでください。

しかし、多くの公式文書の書き方が悪く、しばらく読むと混乱してしまうのが残念です。

最近、openfeign ソース コードを研究していたときに、ソース コード内に重要な注釈 @Import を見つけました。

プロジェクト起動クラス:

/**
 * @author tianwc  公众号:java后端技术全栈、面试专栏
 * @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后端技术全栈、面试专栏
 * @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后端技术全栈、面试专栏
 * @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 のキー コードが次のとおりであることがわかります:

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

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

#userFeignClient.invitedRegister(invitedDto);

</blockquote><h3 id="span-style-display-none-span-code-EnableFeignClients-code-span-style-display-none-span"><span style="display: none;"></span>@<code>EnableFeignClients

@EnableFeignClients这个注解在启动类上,我们肯定要重点关注。

小技巧:凡是以@Enable开头的各种注解基本上都是开启xxxx。比如:@EnableFeignClients表示开启feign客户端。

我们进入@EnableFeignClients

/**
 * @author tianwc  公众号:java后端技术全栈、面试专栏
 * @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 {};
}
ログイン後にコピー

我们通常只需要关心属性basePackages,表示我们需要扫描的包目录。

如果既没有指定basePackages,也没有指定basePackageClasses,则采用启动类所在的目录作为包扫描路径。默认是这种情况。

本文重点来了,在这个注解@EnableFeignClients上有个注解@Import(FeignClientsRegistrar.class),这里到底是有什么作用?

@Import()

@Import()アノテーションは Spring バージョン 3.0 で導入されました。リテラルの意味は import.

@Import アノテーションの完全なクラス名は org.springframework.context.annotation.Import です。これには Class<?>[] 型のデフォルト値属性が 1 つだけあり、1 つ以上の Class オブジェクトを渡すことができることを示します。

アノテーションからわかるように、アノテーションには次の機能があります:

1 つ以上のコンポーネント クラス (通常は @Configuration 構成クラス) をインポートできます。このアノテーションの機能は次のとおりです。 Spring XML の # と同じ ##要素は同じです。 @Configuration 構成クラス、ImportSelect および ImportBeanDefinitionRegistrar 実装クラスをインポートできます。

Spring 4.2 からは、通常のコンポーネント クラス (通常のクラス) も参照できるようになりました。この関数は、

AnnotationConfigApplicationContext.register() メソッドに似ています。

このアノテーションは、クラスまたはメタアノテーションで宣言できます。

@Configuration で定義されていない XML またはその他のリソースをインポートする必要がある場合は、@ImportResource アノテーションを使用できます。

通常、使用方法は 3 つあります:

  • @Import一个普通类 spring会将该类加载到spring容器中
  • @Import一个类,该类实现了ImportBeanDefinitionRegistrar接口,在重写的registerBeanDefinitions方法里面,能拿到BeanDefinitionRegistry的注册器,能手工往beanDefinitionMap中注册 beanDefinition
  • @Import一个类 该类实现了ImportSelector 重写selectImports方法该方法返回了String[]数组的对象,数组里面的类都会注入到spring容器当中。

下面我们来聊聊@Import在openfeign的这里是起到什么作用。

openfeign中作用

回答上面的代码里

@Import(FeignClientsRegistrar.class)
ログイン後にコピー

这里导入的是FeignClientsRegistrar类,我们再来看看他的类关系图:

Spring Cloud のソースコード分析: パート 1

从类关系图来看,FeignClientsRegistrar实现了ImportBeanDefinitionRegistrar接口。再结合@Import的三种使用方式中的第二种方式,能手工往beanDefinitionMap中注册 beanDefinition

/**
 * @author tianwc  公众号:java后端技术全栈、面试专栏
 * @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中内容如下:

Spring Cloud のソースコード分析: パート 1

但是这里我们只关注defaultConfiguration,我们并有对其进行设置,所以我们可以忽略他。重点是下面这个方法。

registerFeignClients(metadata, registry)

这里就是项目启动时和openfeign相关的核心代码,这也是@EnableFeignClients@FeignClient两个注解关联起来的地方。

我们进入源码中:

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);
            }
        }
    }
}
ログイン後にコピー

代码一行一行看是不是觉得很累,我给你总结好了。

上面的方法分为以下七个步骤:

  • まず、主にスキャン パッケージ パス (basePackages) を取得するために、@EnableFeignClients アノテーションのすべての属性を取得します。
    ##clients 属性は通常、
  • @EnableFeignClients
  • アノテーションでは構成されないため、clients 属性が空のときにロジックに入ります。 pass
    getScanner() メソッドはスキャナー ClassPathScanningCandidateComponentProvider
    を取得し、コンテキスト
  • AnnotationConfigServletWebServerApplicationContext
  • をスキャナーの
    ResourceLoader;## として使用します。 #次に、スキャナー ClassPathScanningCandidateComponentProvider にアノテーション フィルター (AnnotationTypeFilter) を追加し、@FeignClient アノテーションを含む
    BeanDefinition
  • のみをフィルターで除外します。
  • ##次に、getBasePackages(metadata) メソッドを使用して、指定されたパッケージのスキャン パスまたは @EnableFeingClients アノテーション内のスキャン クラスを取得します (取得できない場合)。 、デフォルトでスキャンされます スタートアップ クラスが配置されているパッケージ パス;
  • 次に、コア ロジックに入ります。scanner.findCandidateComponents(basePackage) メソッドを使用して、@FeignClient の注釈が付けられたすべてのインターフェイスをスキャンし、アセンブリの条件を満たします。パッケージ パス ;
  • ##最後に、
    FeignClientConfigurationBeanDefinitionRegistry に登録し、FeignClient の実際の登録操作を実行します。

概要

ソース コード

openfeign の @Import アノテーションがここで使用されます。 FeignClient アノテーションでスキャンされたすべてのインターフェイス クラスは、Bean の形式で Spring IOC コンテナに登録されます。

@Import アノテーションの使用方法を強調しましょう:

  • @Import共通クラス スプリングはクラスをスプリング コンテナにロードします
  • @Import A ImportBeanDefinitionRegistrar インターフェースを実装するクラス。オーバーライドされた registerBeanDefinitions メソッドで、BeanDefinitionRegistry レジスタを取得し、それを beanDefinitionMap の Register に手動で追加できます。 #beanDefinition
  • @Import#ImportSelector OverrideselectImportsMethod このメソッドを実装するクラスString[] 配列のオブジェクトを返し、配列内のクラスが Spring コンテナーに挿入されます。
  • わかりました、今日共有するのはこれですべてです。この Openfeign には興味深いものがたくさんあるので、次回はそれを共有します。

以上がSpring Cloud のソースコード分析: パート 1の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Spring Cloud を賢く使用して、マイクロサービス アーキテクチャの下で負荷分散の問題を解決する Spring Cloud を賢く使用して、マイクロサービス アーキテクチャの下で負荷分散の問題を解決する Jun 23, 2023 pm 01:40 PM

エンタープライズ アプリケーションの複雑さが増すにつれ、アプリケーションを複数のマイクロサービスに分割し、マイクロサービス間の連携を通じてビジネス プロセス全体を完了する企業が増えています。このアーキテクチャ アプローチにより、アプリケーションの安定性と拡張性が向上しますが、負荷分散やサービス検出などの新たな問題も生じます。この記事では、Spring Cloud を使用してマイクロサービス アーキテクチャの下での負荷分散の問題を解決する方法を紹介します。負荷分散とは何ですか?負荷分散 (LoadBalancing) は、複数のサーバーとネットワークのバランスをとることを指します。

Spring Cloud のソースコード分析: パート 1 Spring Cloud のソースコード分析: パート 1 Aug 15, 2023 pm 04:04 PM

個人的には、ソースコードを読むには使えることが前提だと思っています、慣れてしまえば他の人がどのように実装したか推測できるようになりますし、関連する公式ドキュメントがある場合は公式ドキュメントを読みましょう。

サービス指向の Spring Cloud マイクロサービス開発 サービス指向の Spring Cloud マイクロサービス開発 Jun 23, 2023 pm 12:30 PM

インターネットの発展とテクノロジーの継続的な更新により、従来の単一アプリケーションではユーザーのニーズを満たすことができなくなり、マイクロサービスの概念が登場しました。 SpringCloud は、Pivo​​tal によって開始されたマイクロサービス開発ツールキットで、開発者にマイクロサービス アーキテクチャ アプリケーションを構築、デプロイ、管理するための非常に便利な方法を提供します。この記事では、SpringCloud の概念とアーキテクチャ、マイクロサービス開発プロセス、およびサービス指向 SpringCloud マイクロサービス開発について詳しく紹介します。

Java を使用して Spring Cloud Kubernetes に基づくコンテナ オーケストレーション アプリケーションを開発する方法 Java を使用して Spring Cloud Kubernetes に基づくコンテナ オーケストレーション アプリケーションを開発する方法 Sep 20, 2023 am 11:15 AM

Java を使用して Spring Cloud Kubernetes に基づいたコンテナ オーケストレーション アプリケーションを開発する方法 コンテナ テクノロジの開発と広範な適用に伴い、コンテナ オーケストレーション ツールは開発者にとって不可欠な部分になりました。 Kubernetes は最も人気のあるコンテナ オーケストレーション ツールの 1 つとして業界標準になっています。この状況において、Spring Cloud と Kubernetes を組み合わせることで、コンテナ オーケストレーションに基づいたアプリケーションを簡単に開発できます。この記事で詳しく紹介します

Spring Cloud マイクロサービス アーキテクチャのデプロイと運用 Spring Cloud マイクロサービス アーキテクチャのデプロイと運用 Jun 23, 2023 am 08:19 AM

インターネットの急速な発展に伴い、エンタープライズレベルのアプリケーションの複雑さは日に日に増しています。この状況に対応して、マイクロサービス アーキテクチャが登場しました。そのモジュール性、独立した展開、および高い拡張性により、今日ではエンタープライズレベルのアプリケーション開発の最初の選択肢となっています。 Spring Cloud は優れたマイクロサービス アーキテクチャとして、実際のアプリケーションで大きな利点を示しています。この記事では、SpringCloud マイクロサービス アーキテクチャのデプロイと運用保守について紹介します。 1. SpringCloud マイクロサービス アーキテクチャ SpringCloud をデプロイする

Java 言語での Spring Cloud フレームワークの紹介 Java 言語での Spring Cloud フレームワークの紹介 Jun 09, 2023 pm 10:54 PM

Java 言語での Spring Cloud フレームワークの紹介 クラウド コンピューティングとマイクロサービスの人気に伴い、Spring Cloud フレームワークは Java 言語でクラウド ネイティブ アプリケーションを構築するための好ましいフレームワークの 1 つになりました。この記事では、Spring Cloud フレームワークの概念と機能、および Spring Cloud を使用してマイクロサービス アーキテクチャを構築する方法を紹介します。 SpringCloud の概要 SpringCloud フレームワークは、SpringBoot に基づくマイクロサービス フレームワークです。それはです

分散ロックを実装するための Spring Cloud マイクロサービスの実践 分散ロックを実装するための Spring Cloud マイクロサービスの実践 Jun 22, 2023 pm 11:28 PM

マイクロサービス アーキテクチャの人気に伴い、ますます多くの企業開発チームが Spring Cloud を使用して独自のマイクロサービス システムを構築し始めています。分散環境では、分散ロックの実装は重要な技術的課題です。この記事では、Spring Cloud フレームワークの下で分散ロックのマイクロサービス プラクティスを実装する方法を紹介します。まず、分散ロックとは何かを理解する必要があります。分散ロックは、共有リソースへのアクセスを保護するために使用されるテクノロジーであり、分散環境で複数のノードが同じリソースを同時に変更したり、変更したりしないようにすることができます。

Spring Cloud マイクロサービスとコンポーネント化の組み合わせ Spring Cloud マイクロサービスとコンポーネント化の組み合わせ Jun 23, 2023 am 10:21 AM

インターネット技術の継続的な発展に伴い、ますます多くの企業がマイクロサービス アーキテクチャを採用してシステムを構築し始めています。 SpringCloud は、この文脈で急速に登場したマイクロサービス フレームワークです。これに基づいて、この記事では SpringCloud マイクロサービスとコンポーネント化の組み合わせについて説明し、その利点と実装方法を分析します。 1. SpringCloud マイクロサービスの概要 SpringCloud は、SpringBoot プロジェクトのアップグレードされたバージョンであり、多数のツールを提供します。

See all articles