38

我在自动连接另一个项目的假客户端时遇到问题。似乎没有生成和注入 feign 客户端的实现。

这是我得到的错误。

org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'passportRestController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: 
Could not autowire field: private com.wstrater.service.contacts.client.ContactService com.wstrater.service.passport.server.controllers.PassportRestController.contactService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type [com.wstrater.service.contacts.client.ContactService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: 
{@org.springframework.beans.factory.annotation.Autowired(required=true)}

伪装客户端非常简单。为简洁起见,我删除了导入。

package com.wstrater.service.contacts.client;

@FeignClient("contact-service")
public interface ContactService {

  @RequestMapping(method = RequestMethod.GET, value = ContactConstants.CONTACTS_USER_ID_PATH)
  public Collection<Contact> contactsByUserId(@PathVariable("userId") String userId);

}

我将组件扫描添加到我的项目中,以包含应用程序及其控制器,并将 feign 客户端包含在另一个项目中。

package com.wstrater.service.passport.server;

@EnableEurekaClient
@EnableFeignClients
@SpringCloudApplication
@ComponentScan({"com.wstrater.service.passport.server",
                "com.wstrater.service.contacts.client"})
public class PassportServiceApplication {

  public static void main(String[] args) {
    ApplicationContext ctx = SpringApplication.run(PassportServiceApplication.class, args);
  }

}

为简洁起见,删除了大部分导入的其余控制器。

package com.wstrater.service.passport.server.controllers;

import com.wstrater.service.contacts.client.ContactService;

@RestController
public class PassportRestController {

  @Autowired
  private ContactService contactService;

  @RequestMapping(PassportContstants.PASSPORT_USER_ID_PATH)
  public ResponseEntity<Passport> passportByUserId(@PathVariable String userId) {
    ResponseEntity<Passport> ret = null;

    Collection<Contact> contacts = contactService.contactsByUserId(userId);
    if (contacts == null || contacts.isEmpty()) {
      ret = new ResponseEntity(HttpStatus.NOT_FOUND);
    } else {
      ret = ResponseEntity.ok(new Passport(contacts));
    }

    return ret;
  }

}

我曾尝试在不同的项目和不同的包中定义 feign 客户端接口,并且仅在将其与应用程序放在同一个包中时才看到成功。这让人相信这是一个组件扫描问题,即使我将包包含在扫描中。我想将 feign 客户端接口保留在共享项目中,以定义可重用的“合同”,并让每个项目具有唯一的包结构,而不是使用使用它的应用程序定义 feign 客户端。

谢谢,韦斯。

4

4 回答 4

88

你需要告诉 Feign 扫描器在哪里找到接口。

您可以使用@EnableFeignClients(basePackages = {"my.external.feign.client.package", "my.local.package"}).

于 2015-05-14T18:13:59.903 回答
2

直接类/接口名称可以如下给出

@EnableFeignClients(basePackageClasses=com.abc.xxx.client.XXFeignClient.class)

此参数接受单个或多个类名

于 2017-11-27T11:09:13.700 回答
1

我的主类在包“com.abc.myservicename”中,我的主类名是“myservicename.java”。我在我的主类中使用了 @SpringBootApplication(scanBasePackages="com.abc") 注释。

将主类包名称更改为“com.abc”为我解决了这个问题。

于 2019-10-02T05:53:47.043 回答
0

谢谢您的帮助。我在 @EnableFeignClients(basePackages = {}) 中添加了正确的外部包它仍然没有拿起 feign 客户端实现。

我有一个 PACT 合同测试,我在其中自动装配 api 客户端 bean。我使用了@ExtendWith(SpringExtension.class)这是问题所在。我替换为@SpringBootTest,它允许在此类中公开 feign 客户端 bean

于 2021-08-05T15:26:50.927 回答