spring cloud配置遇到的bean not found问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring cloud配置遇到的bean not found问题相关的知识,希望对你有一定的参考价值。

参考技术A 写这篇笔记的原因是在配置微服务过程中,出现了如下错,原因很简单,但是因为不够熟悉困惑了一阵子。

Field userFeignClient in cn.tearn.testa.demoa.DemoaController required a bean of type 'cn.tearn.demobsdk.restful.UserFeignClientB' that could not be found.

Action:

Consider defining a bean of type 'cn.tearn.demobsdk.restful.UserFeignClientB' in your configuration.

场景:

创建两个微服务,服务消费者demoa和服务提供者demob,书上或网上一些例子大部分把demob的FeignClient接口写在demoa工程里,这样服务消费者在使用的时候都写一遍FeignClient,这是很麻烦,也是很多余的事情。把FeignClient做为一个单独的module,那么消费者要用的时候直接添加依赖就可以了,具体内容就不写了,下面列出架构,如下图:

服务消费额者:

这个module里也加了调用服务提供者的FeignClient(UserFeignClient),不用的,不推荐。

服务提供者:

服务提供者之FeignClient:

demoa添加demob-sdk以后之后,

在Controller里直接注入UserFeignClientB,demoa工程在启动的时候文章开头的错,

启动异常:

Field userFeignClient in cn.tearn.testa.demoa.DemoaController required a bean of type 'cn.tearn.demobsdk.restful.UserFeignClientB' that could not be found.

Action:

Consider defining a bean of type 'cn.tearn.demobsdk.restful.UserFeignClientB' in your configuration.

在deomoaApplication加了 @ComponetScan 扫描cn.tearn.demobsdk.restful,不行!改成 @EnableFeignClients ("cn.tearn.demobsdk.restful")就ok了,不加这两个注解导致的错误信息是一样的,原因可是不一样。回想上面demoa贴图里也有一个FeignClient类,为什么启动没问题也能调通呢?因为我在demoaApplication加了@EnableFeignClients,它能扫到当前所在的包。

这样虽然问题解决了,但是需要每个消费者都需要写一遍还是比较麻烦的,另外一种做法就是配置写在demobsdk里。

在demobsdk moudle的META-INF下添加spring.factories文件(直接放在rescources下也一样),内容:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\

  cn.tearn.demobsdk.sdkConfig

sdkConfig.java里加上一句@EnableFeignClients("cn.tearn.demobsdk.restful")就可以了,如下图:

spring cloud gateway 负载均衡流程

网关被扫描后会注册四个核心配置类,当然在配置类中仍然有各种流程中需要的bean后面会详细解释。

l  GatewayAutoConfiguration  网关基础配置类,当中承载着核心的配置逻辑

l  GatewayClassPathWarningAutoConfiguration  网关类加载配置类,就是用于校验是否加载的时webFlux依赖,而不是普通的web依赖。

l  GatewayLoadBalancerClientAutoConfiguration  网关客户端负载均衡配置类

l  GatewayRedisAutoConfiguration   网关限流器配置类

我们先回过头,假如你已经搭建了一个gateway的demo,那么在网关中进行负载均衡,会添加注解如下:

@RibbonClient(name = "pay-server", configuration = {IRule2.class})

@Configuration
@ConditionalOnClass({LoadBalancerClient.class, RibbonAutoConfiguration.class, DispatcherHandler.class})
@AutoConfigureAfter(RibbonAutoConfiguration.class)
public class GatewayLoadBalancerClientAutoConfiguration {

    // GlobalFilter beans

    @Bean
    @ConditionalOnBean(LoadBalancerClient.class)
    public LoadBalancerClientFilter loadBalancerClientFilter(LoadBalancerClient client) {
        return new LoadBalancerClientFilter(client);
    }

}
RibbonClientConfigurationRegistrar
private void registerClientConfiguration(BeanDefinitionRegistry registry,
            Object name, Object configuration) {
        BeanDefinitionBuilder builder = BeanDefinitionBuilder
                .genericBeanDefinition(RibbonClientSpecification.class);
        builder.addConstructorArgValue(name);
        builder.addConstructorArgValue(configuration);
        registry.registerBeanDefinition(name + ".RibbonClientSpecification",
                builder.getBeanDefinition());
    }

 

以上是关于spring cloud配置遇到的bean not found问题的主要内容,如果未能解决你的问题,请参考以下文章

深入理解Spring Cloud一(4)Bean中的属性是如何刷新的?

Spring Cloud Eureka 源码分析 —— Client端

spring cloud config---Could not resolve placeholder 'xxx' in string value "${xxx}"

Spring Cloud 默认配置文件

Spring定时任务 Could not find default TaskScheduler bean异常处理

Spring Cloud Commons教程Spring RestTemplate作为负载平衡器客户端