Je ne parviens pas à connecter automatiquement un client factice à un autre projet. Il semble que l'implémentation du client simulé ne soit ni générée ni injectée.
C'est l'erreur que je reçois.
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)}
Le client feint est assez simple. J'ai supprimé les importations par souci de brièveté.
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);
}
J'ai ajouté l'analyse de composant à mon projet pour inclure l'application et ses contrôleurs, ainsi que le client simulé dans l'autre projet.
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);
}
}
Le reste du contrôleur dont la plupart des importations ont été supprimées pour des raisons de concision.
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;
}
}
J'ai essayé de définir l'interface client fictive dans différents projets et différents packages et je n'ai obtenu de succès que dans le même package que l'application. Cela fait croire qu'il s'agit d'un problème d'analyse de composant même si j'inclus le package dans l'analyse. Je souhaite conserver l'interface client fictif dans un projet partagé pour définir un "contrat" réutilisable et pour que chaque projet ait une structure de package unique au lieu de définir le client fictif avec l'application qui l'utilise.
Merci Wes.
Vous devez indiquer au scanner Feign où localiser les interfaces.
Vous pouvez utiliser @EnableFeignClients(basePackages = {"my.external.feign.client.package", "my.local.package"})
.
Le nom direct de classe/interface peut être donné comme ci-dessous
@EnableFeignClients(basePackageClasses=com.abc.xxx.client.XXFeignClient.class)
Ce paramètre accepte un nom de classe unique ou multiple