首页 > 编程语言 >Feign源码解析:初始化过程(二)

Feign源码解析:初始化过程(二)

时间:2023-12-23 23:14:02浏览次数:42  
标签:初始化 Feign spring nacos springframework 源码 loadbalancer org cloud

背景

上一篇介绍了Feign源码初始化的一部分,内容主要是,@EnableFeignClients、@FeignClient这些注解,都支持设置一些自定义的配置类:

A custom @Configuration for all feign clients. Can contain override @Bean definition
 for the pieces that make up the client, for instance feign.codec.Decoder, 
feign.codec.Encoder, feign.Contract.

每个被@EnableFeignClients、@FeignClient注解的类都会对应生成一个bean,类型为:org.springframework.cloud.openfeign.FeignClientSpecification:

public class FeignClientSpecification implements NamedContextFactory.Specification {

	private String name;

	private Class<?>[] configuration;

即使没定义自定义的配置类,这个bean照样生成,只是里面的configuration字段是null。

这些bean都不是spring boot那种自动装配类,因为自动装配类一般来说,都是带条件的,比如要检测到classpath中有某个类,某个property的值等于xxx。

今天,就简单介绍下,Feign启动过程中,自动装配的那些类。

项目简介

自动装配有很多条件都是基于类是否存在来判断,咱们先看看classpath中有啥,主要就是web、nacos服务发现、feign、loadbalancer。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

当然,这里是要通过nacos进行服务发现的:

spring.cloud.nacos.discovery.username=111
spring.cloud.nacos.discovery.password=222
spring.cloud.nacos.discovery.server-addr=1.1.1.1:8848
spring.cloud.nacos.discovery.namespace=test

Feign调用的client代码:

package com.example.demo.demos.nacosdiscoveryconsumer;

import org.springframework.cloud.openfeign.FeignClient;

@FeignClient("echo-service-provider") 
public interface EchoService {

    @GetMapping("/echo/{message}")
    String echo(@PathVariable("message") String message);
}

手动梳理装配类

稍微了解spring boot的自动装配的话,大概知道,在starter那些依赖中,jar文件一般没有实质内容,没有class啥的,主要的内容还是pom文件,里面定义了该starter依赖的那些jar:

image-20231223214040162

pom依赖主要包含feign自身、spring对feign的集成、spring-loadbalancer:

<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-core</artifactId>
    <version>11.10</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-openfeign-core</artifactId>
    <version>3.1.7</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
    <version>3.1.6</version>
    <scope>compile</scope>
    <optional>true</optional>
</dependency>

我们看看spring-cloud-openfeign-core这个依赖,这个spring-cloud-openfeign-core-3.1.7.pom呢,里面定义了很多底层依赖,而spring-cloud-openfeign-core-3.1.7.jar,则不再是无实质内容了:

image-20231223214602025

大家看到我上图框的spring.factories文件,大概就知道,这个东西是和自动装配有关系的。

我们打开看看:

image-20231223214714380

里面主要就是定义了,需要自动装配的配置类。

比如第一个类:org.springframework.cloud.openfeign.hateoas.FeignHalAutoConfiguration

image-20231223214909861

这些类得特征是:都是有条件的,这也符合自动装配的逻辑,自动装配就是猜测你需要某些类,猜测那是需要依据的,依据就是:检查你的各种上下文,就跟现在那些短视频推荐一样的,猜你喜欢嘛。

这边简单汇总下,就是这5个自动装配类:

org.springframework.cloud.openfeign.hateoas.FeignHalAutoConfiguration,\
org.springframework.cloud.openfeign.FeignAutoConfiguration,\
org.springframework.cloud.openfeign.encoding.FeignAcceptGzipEncodingAutoConfiguration,\
org.springframework.cloud.openfeign.encoding.FeignContentGzipEncodingAutoConfiguration,\
org.springframework.cloud.openfeign.loadbalancer.FeignLoadBalancerAutoConfiguration

接下来,看看spring-loadbalancer那个依赖,盘一盘它:

spring-cloud-starter-loadbalancer-3.1.6.jar,和其他starter一样,里面啥都没有;

spring-cloud-starter-loadbalancer-3.1.6.pom,主要依赖如下:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-loadbalancer</artifactId>
    <version>3.1.6</version>
    <scope>compile</scope>
</dependency>

该依赖如下:

image-20231223215630377

主要包含如下几个自动装配类:

org.springframework.cloud.loadbalancer.config.LoadBalancerAutoConfiguration,\
org.springframework.cloud.loadbalancer.config.BlockingLoadBalancerClientAutoConfiguration,\
org.springframework.cloud.loadbalancer.config.LoadBalancerCacheAutoConfiguration,\
org.springframework.cloud.loadbalancer.security.OAuth2LoadBalancerClientAutoConfiguration,\
org.springframework.cloud.loadbalancer.config.LoadBalancerStatsAutoConfiguration

至于nacos,也是一样的套路盘起来,但是,它要直接一点,直接starter里面就是实质内容了:

image-20231223215905202

引入的自动配置类有:

  com.alibaba.cloud.nacos.discovery.NacosDiscoveryAutoConfiguration,\
  com.alibaba.cloud.nacos.endpoint.NacosDiscoveryEndpointAutoConfiguration,\
  com.alibaba.cloud.nacos.registry.NacosServiceRegistryAutoConfiguration,\
  com.alibaba.cloud.nacos.discovery.NacosDiscoveryClientConfiguration,\
  com.alibaba.cloud.nacos.discovery.reactive.NacosReactiveDiscoveryClientConfiguration,\
  com.alibaba.cloud.nacos.discovery.configclient.NacosConfigServerAutoConfiguration,\
  com.alibaba.cloud.nacos.loadbalancer.LoadBalancerNacosAutoConfiguration,\
  com.alibaba.cloud.nacos.NacosServiceAutoConfiguration,\
  com.alibaba.cloud.nacos.util.UtilIPv6AutoConfiguration

但以上就完了吗,不是。spring-cloud-loadbalancer是属于spring-cloud-commons的,在commons的jar包中,也有相关的自动配置类:

image-20231223223204449

org.springframework.cloud.client.loadbalancer.AsyncLoadBalancerAutoConfiguration,\
org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration,\
org.springframework.cloud.client.loadbalancer.LoadBalancerDefaultMappingsProviderAutoConfiguration,\
org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerBeanPostProcessorAutoConfiguration,\
org.springframework.cloud.client.loadbalancer.reactive.ReactorLoadBalancerClientAutoConfiguration,\

这边汇总下吧:

org.springframework.cloud.openfeign.hateoas.FeignHalAutoConfiguration,\
org.springframework.cloud.openfeign.FeignAutoConfiguration,\
org.springframework.cloud.openfeign.encoding.FeignAcceptGzipEncodingAutoConfiguration,\
org.springframework.cloud.openfeign.encoding.FeignContentGzipEncodingAutoConfiguration,\
org.springframework.cloud.openfeign.loadbalancer.FeignLoadBalancerAutoConfiguration

org.springframework.cloud.loadbalancer.config.LoadBalancerAutoConfiguration,\
org.springframework.cloud.loadbalancer.config.BlockingLoadBalancerClientAutoConfiguration,\
org.springframework.cloud.loadbalancer.config.LoadBalancerCacheAutoConfiguration,\
org.springframework.cloud.loadbalancer.security.OAuth2LoadBalancerClientAutoConfiguration,\
org.springframework.cloud.loadbalancer.config.LoadBalancerStatsAutoConfiguration


com.alibaba.cloud.nacos.discovery.NacosDiscoveryAutoConfiguration,\
com.alibaba.cloud.nacos.endpoint.NacosDiscoveryEndpointAutoConfiguration,\
com.alibaba.cloud.nacos.registry.NacosServiceRegistryAutoConfiguration,\
com.alibaba.cloud.nacos.discovery.NacosDiscoveryClientConfiguration,\
com.alibaba.cloud.nacos.discovery.reactive.NacosReactiveDiscoveryClientConfiguration,\
com.alibaba.cloud.nacos.discovery.configclient.NacosConfigServerAutoConfiguration,\
com.alibaba.cloud.nacos.loadbalancer.LoadBalancerNacosAutoConfiguration,\
com.alibaba.cloud.nacos.NacosServiceAutoConfiguration,\
com.alibaba.cloud.nacos.util.UtilIPv6AutoConfiguration

org.springframework.cloud.client.loadbalancer.AsyncLoadBalancerAutoConfiguration,\
org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration,\
org.springframework.cloud.client.loadbalancer.LoadBalancerDefaultMappingsProviderAutoConfiguration,\
org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerBeanPostProcessorAutoConfiguration,\
org.springframework.cloud.client.loadbalancer.reactive.ReactorLoadBalancerClientAutoConfiguration,\

这一下,就是几十个自动装配类,真他么多。

注意,这里面还有两个名字相同,包名不同的:

image-20231223223506657

自动配置类最终引入了哪些bean

自动装配类都是相当复杂的,基于各种条件的计算,很多都不是一眼就能看出来的,有些和顺序还息息相关,比如,ConditionalOnMissingBean,这个就很有意思,在没有bean存在的情况下才自动装配,但我之前遇到过,有两个自动装配类,都加了这个注解,那,最终到底是哪个自动装配进去呢?

所以,如果项目复杂,可以考虑打开如下日志开关:

logging.level.org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener=DEBUG

就会打印如下的日志,哪些装配了,哪些没装配,一目了然:

image-20231223220710773

spring boot actuator的actuator/conditions也支持动态查看这个信息,甚至可以看到各个spring容器的:

image-20231223221027037

如果想知道某个自动装配类中,哪些bean匹配了,哪些bean没匹配上,只能ctrl + f了,比如Feign这个装配类:

org.springframework.cloud.openfeign.FeignAutoConfiguration

image-20231223221733255

相当于匹配上了如下两个bean:

image-20231223222023927

这边累计汇总下,装配成功的:

  • org.springframework.cloud.openfeign.FeignAutoConfiguration及内部的:
    FeignAutoConfiguration、
    FeignAutoConfiguration.DefaultFeignTargeterConfiguration
    FeignAutoConfiguration.DefaultFeignTargeterConfiguration#feignTargeter

  • org.springframework.cloud.openfeign.loadbalancer.FeignLoadBalancerAutoConfiguration,内部类/method:无,这个类是靠import引入其他configuration的

  • org.springframework.cloud.loadbalancer.config.LoadBalancerAutoConfiguration

    LoadBalancerAutoConfiguration#zoneConfig

  • org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration

    org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration#loadBalancerRequestFactory

    org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration#loadBalancerRequestFactory

    org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration.LoadBalancerInterceptorConfig

    org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration.LoadBalancerInterceptorConfig#restTemplateCustomizer

  • BlockingLoadBalancerClientAutoConfiguration

    BlockingLoadBalancerClientAutoConfiguration#blockingLoadBalancerClient

    BlockingLoadBalancerClientAutoConfiguration#loadBalancerServiceInstanceCookieTransformer

    BlockingLoadBalancerClientAutoConfiguration#xForwarderHeadersTransformer

  • LoadBalancerCacheAutoConfiguration

    内部略,太多了,写了也记不住

  • NacosDiscoveryAutoConfiguration

    NacosDiscoveryAutoConfiguration#nacosProperties

    NacosDiscoveryAutoConfiguration#nacosServiceDiscovery

  • NacosServiceRegistryAutoConfiguration

    NacosServiceRegistryAutoConfiguration#nacosAutoServiceRegistration

    NacosServiceRegistryAutoConfiguration#nacosRegistration

  • NacosDiscoveryClientConfiguration

  • NacosServiceAutoConfiguration

  • UtilIPv6AutoConfiguration

  • AsyncLoadBalancerAutoConfiguration

  • LoadBalancerDefaultMappingsProviderAutoConfiguration

以上都是匹配上的,没匹配的都没写。这边写了一抹多,供查阅吧,重点的有一个要先摘出来说,它是属于没匹配上的:

LoadBalancerNacosAutoConfiguration:
      Did not match:
         - @ConditionalOnProperty (spring.cloud.loadbalancer.nacos.enabled=true) did not find property 'spring.cloud.loadbalancer.nacos.enabled' (OnPropertyCondition)

这是一个nacos包里的关于loadbalancer的自动配置类,当初就是因为这个类,让我遇到了些问题,才好好研究了下feign,写了这几篇,可以说的上是为了这盘醋包了这顿饺子,后面的文章会再说说这个类。

标签:初始化,Feign,spring,nacos,springframework,源码,loadbalancer,org,cloud
From: https://www.cnblogs.com/grey-wolf/p/17923800.html

相关文章

  • Flink源码解析(九)——ExecutionGraph生成过程解析
    一、ExecutionGraph介绍介绍ExecutionGraph是调度Flink作业执行的核心数据结构,包含了作业中所有并行执行的Task信息、Task之间的关联关系、数据流转关系。相比于StreamGraph、JobGraph,ExecutionGraph加入了并行度的概念,成为真正可调度的图结构。下图是一个ExecutionGraph的简单示......
  • 医院患者职工食堂订餐系统食堂报餐系统医院订餐系统源码
    医院订餐系统,食堂报餐,一床一码,手机扫码核销主要功能:患者管理:患者订单信息,患者床位信息菜品管理:价格,图片,规格订餐类型管理:早中晚,日期病房床位管理:科室->床位收入汇总 下单后食堂打印机出票开发语言:uniapp前端+tinkphp后台+mysql数据库  ......
  • Spring MVC 源码分析 - HandlerMapping 组件(三)之 AbstractHandlerMethodMapping
    HandlerMapping组件HandlerMapping组件,请求的处理器匹配器,负责为请求找到合适的 HandlerExecutionChain 处理器执行链,包含处理器(handler)和拦截器们(interceptors)handler 处理器是Object类型,可以将其理解成HandlerMethod对象(例如我们使用最多的 @RequestMapping 注解所标......
  • spring-jcl 模块源码分析
    目录简介源码分析总结简介spring-jcl是spring用于处理日志打印的模块,被spring-core所依赖:jcl全称是JakartaCommonsLogging,是apache提供的日志门面(功能同slf4j),日志门面利用设计模式中的门面模式提供统一的日志接口,实际的日志实现可以任意更换。不过jcl支持的日志实现有限,已......
  • 基于SpringBoot+Vue的文理医院预约挂号系统设计实现(源码+lw+部署文档+讲解等)
    (文章目录)前言:heartpulse:博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌:heartpulse:......
  • 源码安装pgsql16.1
    源码安装pgsql16.1进入postgresql官网下载源码包postgresql源码包下载地址这里以目前最新的pgsqlv16.1为例创建组:postgresgroupaddpostgres创建用户postgres并加入组postgres中useradd-gpostgrespostgres解压源码包tar-xfpostgresql-16.1.tar.gz进入解压后的目......
  • 短视频app源码,实现幂等设计的重要方式
    短视频app源码,实现幂等设计的重要方式一、取消重试取消重试有两种方法,第一是设置重试次数为零,第二是选择不重试的集群容错策略。<!--设置重试次数为零--><dubbo:referenceid="helloService"interface="com.java.front.dubbo.demo.provider.HelloService"retries="......
  • java云HIS源码:云端部署,支持多医院、多门诊、多机构、实现医疗数据共享与交换
    系统概述云HIS是针对中小医疗机构推出的一套基于云端的云HIS服务平台,借助云his,将医院业务流程化,大大提高医院的服务效率和服务质量,为客户提供医院一体化的信息解决方案。云his系统是用计算机网络将医院内各个环节(门诊计价收费、门诊药房、住院信息、临床科室、医技、财务等)全部连......
  • Spring源码深度解析_源码构建
    源码构建1.下载下载Spring源码,这里以5.0.2.RELEASE为例,下载地址<https://github.com/spring-projects/spring-framework/archive/v5.0.2.RELEASE.zip>Spring源码中有很多module,在这里做出简单说明:spring-jcl:spring封装的日志框架。spring-core:spring核心依赖,包含Spring框......
  • [C++从入门到精通] 10.回顾类内初始化、默认构造函数、=default
    ......