【问题标题】:Openfeign + Spring cloud : Field required a bean of type that could not be foundOpenfeign + Spring cloud:字段需要找不到类型的bean
【发布时间】:2020-03-23 16:58:45
【问题描述】:

我有一个关于 spring 和 openfeign 的问题,我认为你可以帮助我。

我有一个pom文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>xx.yyy</groupId>
    <artifactId>component</artifactId>
    <version>1.0.0</version>
    <name>component</name>

    <properties>
        <java.version>1.8</java.version>
        <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
        <pact.version>3.6.7</pact.version>
        <spring-cloud.version>Greenwich.SR4</spring-cloud.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.10.RELEASE</version>
        <relativePath />
    </parent>


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
......
<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
......

我在主类中声明了以下配置:

@SpringBootApplication(scanBasePackages = {"xx.yyy", "xx.yyy.rest.client"}, exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
@EnableAsync
@Import({P2OrchestratorApplicationConfig.class})
public class P2OrchestratorApplication {

    public static void main(String[] args) {
        SpringApplication.run(P2OrchestratorApplication.class, args);
    }
}

我有一个自定义的 feign 配置类:

@Configuration
@EnableFeignClients()
@ImportAutoConfiguration({FeignAutoConfiguration.class})
public class FeignConfig {

    @Bean
    public OkHttpClient client() {
        return new OkHttpClient();
    }
    
    @Bean
    public Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
    
    @Bean
    public Contract feignContract() {
        return new feign.Contract.Default();
    }
}

我有一个开放的 feign 客户端如下:

@FeignClient(name="legacyClient", value = "legacyClient", url = "${uri.microservice.legacy}", configuration = FeignConfig.class)
public interface LegacyClient {
    
    @PatchMapping(value = "/legacy/xxx/cleanLine/{authorizationCode}", produces = { MediaType.APPLICATION_JSON_VALUE })
    public ResponseEntity<Boolean> cleanLine(@PathVariable("authorizationCode") Long authorizationCode, @RequestParam(required = true) Long lineNumber);
    

}

最后是我需要在其中使用此客户端的组件:

@Log4j
@Component("p2ProcessAlgorithm")
public class P2ProcessAlgorithm {

@Autowired
@Qualifier("legacyClient")
private LegacyClient legacyClient;

public final void process(){

Long authorizationCode = 123L;
Long lineNumber = 1L;
Boolean isClean= this.legacClient.cleanLine(authorizationCode, lineNumber);
......
}

但应用程序给了我下一条消息:

***************************
APPLICATION FAILED TO START
***************************

Description:

Field legacyClient in xxx.yyy.p2.structure.P2ProcessAlgorithm required a bean of type 'xxx.yyy.rest.client.LegacyClient' that could not be found.

The injection point has the following annotations:
    - @org.springframework.beans.factory.annotation.Autowired(required=true)
    - @org.springframework.beans.factory.annotation.Qualifier(value=p2AsyncOrchestratorService)


Action:

Consider defining a bean of type 'xxx.yyy.rest.client.LegacyClient' in your configuration.

我尝试了几种配置,但无法让 openfeign 客户端成为 P2ProcessAlgorithm 类中可识别的 bean。

你有什么想法吗?

提前致谢

【问题讨论】:

    标签: java rest spring-boot autowired openfeign


    【解决方案1】:

    可能有帮助的几点:

    首先: 为什么要使用限定符将LegacyClient bean 注入到您的服务中?有很多吗?一般来说,一个接口应该被包装到代理中,并作为单个 bean 放入应用程序上下文中,所以在我的理解中,这里不需要限定符。

    另一个问题:

    看起来@FeignClient 注释没有被处理。因此不会创建代理。为了检查这一点,在配置 FeignConfig 一些 bean 中放置一个断点/创建一个无操作构造函数并检查它是否被调用(或者可能会放置日志消息只是为了查看它是否有效)。

    您尚未发布包结构,但可能是包扫描机制未找到此配置,因此未创建。

    【讨论】:

      【解决方案2】:

      首先感谢您的回复。

      我回答了你的第一个问题, 是的,这只是一种习惯。我可以毫无问题地消除它。没有更多的 Bean 占据同一个接口。这不是问题。

      回复您的第二条评论,您是绝对正确的。

      将构建器添加到 FeignConfig 配置类。添加日志和断点,不要停在那里。

      附上一个ss的包结构,看看能不能帮我发现我的问题。

      project package structure

      • 在ms.config包中,我有FeignConfig配置类
      • 在rest.client包里,我有Feign Client的所有接口
      • 在 ms 包中是带有符号 SpringBootApplication 的主类
      • 在 ms.p2.structure 包中是调用 feign 客户端的类。

      非常感谢您。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-05-09
        • 2019-12-05
        • 1970-01-01
        • 2018-05-11
        • 1970-01-01
        • 2019-10-21
        • 2018-09-22
        • 1970-01-01
        相关资源
        最近更新 更多