Reputation: 907
I am having trouble auto wiring a feign client from another project. It appears that the implementation of the feign client is not being generated and injected.
This is the error I am getting.
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)}
The feign client is pretty straight forward. I have removed the imports for brevity.
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);
}
I added the component scan to my project to include the application and it's controllers and to include the feign client in the other project.
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);
}
}
The rest controller with most of the imports removed for brevity.
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;
}
}
I have tried defining the feign client interface in different projects and different packages and have only seen success when it put it in the same package as the application. This make be believe that it is a component scan issue even though I am including the package in the scan. I would like to keep the feign client interface in a shared project to define a reusable "contract" and for each project to have a unique package structure instead of defining the feign client with the application using it.
Thanks, Wes.
Upvotes: 49
Views: 51015
Reputation: 1012
This worked for me. Adding annotation to main class
@EnableFeignClients(defaultConfiguration = {FeignBasicConfiguration.class}, basePackages = {"com.example"})
Upvotes: 1
Reputation: 11
Faced the Same issue where i was not able to @Autowire the FeignClient interface, Changing the Version of Feign Client in pom.xml to 3.0.1 or latest has helped me in resolving the issue.
Upvotes: 0
Reputation: 11
Thanks for the help. I added the right external package in @EnableFeignClients(basePackages = {}) It still did not pick up the feign client implementation.
I had a PACT contract test where I was autowiring the api client bean. I had used @ExtendWith(SpringExtension.class) which was the issue. I replaced with @SpringBootTest, which allowed the feign client bean to be exposed in this class
Upvotes: 0
Reputation: 11
My main class was in package "com.abc.myservicename" and my main class name was "myservicename.java". I was using @SpringBootApplication(scanBasePackages="com.abc") annotation in my main class.
Changing the main class package name to "com.abc" has resolved the issue for me.
Upvotes: 1
Reputation: 2648
Direct Class/Interface name can be given like below
@EnableFeignClients(basePackageClasses=com.abc.xxx.client.XXFeignClient.class)
This parameter accept single or multiple class name
Upvotes: 2
Reputation: 25157
You need to tell the Feign scanner where to locate the interfaces.
You can use @EnableFeignClients(basePackages = {"my.external.feign.client.package", "my.local.package"})
.
Upvotes: 107