从另一个项目注入FeignClient时出错

45

我在尝试使用Feign客户端自动装配另一个项目时遇到了问题。似乎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)}

Feign客户端非常简单明了。出于简洁考虑,我已经删除了导入语句。

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);
  }

}

为了简洁起见,大部分导入模块已被删除的REST控制器。

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客户端。

谢谢,Wes。

6个回答

101

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

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


谢谢。我尝试了一下,因为其他事情突然出现了,但我没有看到任何区别。我将包列表从ComponentScan移动到EnableFeignClients中。@EnableFeignClients(basePackages = {"com.wstrater.service.passport.server", "com.wstrater.service.contacts.client"})。它仍然出现错误。 - Wes
3
我认为问题出在键盘和座位之间,现在它已经能用了。谢谢。 - Wes
谢谢@Wes,这对我很有帮助。 - Jeroen Rondeel
这对我帮助很大。谢谢你! - kholofelo Maloma
在我的测试类中,IntelliJ告诉我有一个错误,但如果我运行测试,它会正常运行。我必须使用@SuppressWarnings("SpringJavaAutowiringInspection")注释测试类,这将抑制这些错误警告。 - alltej

2
可以像下面这样直接给出类/接口的名称:
@EnableFeignClients(basePackageClasses=com.abc.xxx.client.XXFeignClient.class)

该参数接受单个或多个类名。


1
我的主类在包“com.abc.myservicename”中,主类名为“myservicename.java”。我在主类中使用了@SpringBootApplication(scanBasePackages =“com.abc”)注释。
将主类包名称更改为“com.abc”已为我解决了问题。

1
这对我有用。 在主类中添加注释。
@EnableFeignClients(defaultConfiguration = {FeignBasicConfiguration.class}, basePackages = {"com.example"})

0

遇到了同样的问题,我无法@Autowire FeignClient接口,在pom.xml中将Feign Client的版本更改为3.0.1或更高版本有助于解决问题。


0

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接