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


    背景#

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

    Copy
    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:

    Copy
    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。

    Copy
    <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-webartifactId> dependency> <dependency> <groupId>com.alibaba.cloudgroupId> <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId> dependency> <dependency> <groupId>org.springframework.cloudgroupId> <artifactId>spring-cloud-starter-loadbalancerartifactId> dependency> <dependency> <groupId>org.springframework.cloudgroupId> <artifactId>spring-cloud-starter-openfeignartifactId> dependency>

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

    Copy
    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代码:

    Copy
    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:

    Copy
    <dependency> <groupId>io.github.openfeigngroupId> <artifactId>feign-coreartifactId> <version>11.10version> <scope>compilescope> dependency> <dependency> <groupId>org.springframework.cloudgroupId> <artifactId>spring-cloud-openfeign-coreartifactId> <version>3.1.7version> <scope>compilescope> dependency> <dependency> <groupId>org.springframework.cloudgroupId> <artifactId>spring-cloud-starter-loadbalancerartifactId> <version>3.1.6version> <scope>compilescope> <optional>trueoptional> 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个自动装配类:

    Copy
    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,主要依赖如下:

    Copy
    <dependency> <groupId>org.springframework.cloudgroupId> <artifactId>spring-cloud-loadbalancerartifactId> <version>3.1.6version> <scope>compilescope> dependency>

    该依赖如下:

    image-20231223215630377

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

    Copy
    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

    引入的自动配置类有:

    Copy
    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

    Copy
    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,\

    这边汇总下吧:

    Copy
    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存在的情况下才自动装配,但我之前遇到过,有两个自动装配类,都加了这个注解,那,最终到底是哪个自动装配进去呢?

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

    Copy
    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

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

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

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




  • 相关阅读:
    【Spring】bean的生命周期
    NPM 仓库的超集 JSR 来了!
    访问者模式:对象结构的元素处理
    社交网络用户行为分析,各类社交软件用户分析
    vue3+antd+g2plot快速入门
    mac flutter 配置
    【docker】资源使用率验证及告警
    异构混合阶多智能体系统编队控制的分布式优化
    JAVASE(复习)——API(String)
    android 创建桌面快捷方式 ShortCut
  • 原文地址:https://www.cnblogs.com/grey-wolf/p/17923800.html