将自定义假装客户端注入Spring Application

时间:2017-07-18 17:18:43

标签: java spring feign

我目前正试图抓住Spring和Feign。 切入点: 我正在努力修改这个项目中的@FeignClient: Feign Hello World by Walery 以代替

  

WikidataClient

@FeignClient(url = "https://www.wikidata.org/w")
// https://www.wikidata.org/w/api.php?action=wbsearchentities&search=apple&language=en&format=json
public interface WikidataClient {

    @RequestMapping(value = "/api.php?action=wbsearchentities&language=en&format=json", method = GET)
    WebsearchEntities searchForEntities(@RequestParam("search") final String search);
}

使用类似于此处的@Autowired表示法:Section called : Creating Feign Clients Manually

这样做的目的是稍后注入自定义解码器和编码器。我已经对它进行了一段时间的实践,而我所能实现的只是破坏了整个事情。

我从这里和那里收集了一些线索,并设法达到我创建Configuration类的程度:

  

FeignConfig

@Import(FeignClientsConfiguration.class)
public class FeignConfig {
    public WikidataClient fooclient;
    @Autowired
    public FeignConfig(Encoder encoder, Decoder decoder){
        this.fooclient = Feign.builder()
                .encoder(encoder)
                .decoder(decoder)
                .target(WikidataClient.class,"https://www.wikidata.org/w");
    }
}

修改

  

WikidataClient

界面略有

//@FeignClient(url = "https://www.wikidata.org/w")
// https://www.wikidata.org/w/api.php?action=wbsearchentities&search=apple&language=en&format=json
public interface WikidataClient {

    @RequestMapping(value = "/api.php?action=wbsearchentities&language=en&format=json", method = GET)
    WebsearchEntities searchForEntities(@RequestParam("search") final String search);
}

并尝试使用上述类

  

WikidataRunner

@Component
public class WikidataRunner implements CommandLineRunner {
    private final WikidataClient omdbClient;
    @Autowired
    public WikidataRunner(WikidataClient omdbClient){
        this.omdbClient = omdbClient;
        this.feignConfig = new FeignConfig(new Encoder.Default(), new Decoder.Default());
    }

    FeignConfig feignConfig;
    @Override
    public void run(final String... args) throws Exception {
        final WebsearchEntities apple = feignConfig.fooclient.searchForEntities("apple");
        System.out.println(apple);
    }
}

我得到的只是不同类型的Bean错误

  

2017-07-19 08:02:29.056 ERROR 2018 ---线程"主要"   org.springframework.beans.factory.UnsatisfiedDependencyException:   创建名称为' wikidataRunner'的bean时出错在文件中定义   [/home/mibi/IdeaProjects/FUFEign/feign-helloworld/target/classes/codes/walery/research/feign/wikidata/WikidataRunner.class]:   通过构造函数参数表示不满意的依赖关系   类型为[codes.walery.research.feign.wikidata.WikidataClient]的索引0:   :没有类型的限定bean   找到[codes.walery.research.feign.wikidata.WikidataClient]   依赖:预计至少有1个bean有资格成为autowire   这种依赖的候选人。依赖注释:{};嵌套   例外是   org.springframework.beans.factory.NoSuchBeanDefinitionException:没有   合格的bean类型   找到[codes.walery.research.feign.wikidata.WikidataClient]   依赖:预计至少有1个bean有资格成为autowire   这种依赖的候选人。依赖注释:{} [
  主要在   org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)   o.s.boot.SpringApplication at   org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:185)   :应用程序启动失败   org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1143)     在   org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1046)   org.springframework.beans.factory.NoSuchBeanDefinitionException:没有   合格的bean类型   找到[codes.walery.research.feign.wikidata.WikidataClient]   依赖:预计至少有1个bean有资格成为autowire   这种依赖的候选人。依赖注释:{} at   org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)     在   org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)     在   org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1326)   〜[spring-beans-4.2.1.RELEASE.jar:4.2.1.RELEASE] at   org.springframework.beans.factory.support.AbstractBeanFactory $ 1.getObject(AbstractBeanFactory.java:305)     在   org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)     在   org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1072)   〜[spring-beans-4.2.1.RELEASE.jar:4.2.1.RELEASE] at   org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301)     在   org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196)     在   org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:967)   〜[spring-beans-4.2.1.RELEASE.jar:4.2.1.RELEASE] at   org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)     在   org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:834)     在   org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813)   〜[spring-beans-4.2.1.RELEASE.jar:4.2.1.RELEASE] at   org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537)     在   org.springframework.boot.SpringApplication.refresh(SpringApplication.java:667)     在   org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)   〜[spring-beans-4.2.1.RELEASE.jar:4.2.1.RELEASE] at   org.springframework.boot.SpringApplication.doRun(SpringApplication.java:342)     ...省略了18个常见帧   org.springframework.boot.SpringApplication.run(SpringApplication.java:273)     在   org.springframework.boot.SpringApplication.run(SpringApplication.java:980)     在   org.springframework.boot.SpringApplication.run(SpringApplication.java:969)     在   codes.walery.research.feign.FeignHelloworldApplication.main(FeignHelloworldApplication.java:12)   包裹方式:   org.springframework.beans.factory.UnsatisfiedDependencyException:   创建名称为' wikidataRunner'的bean时出错在文件中定义   [/home/mibi/IdeaProjects/FUFEign/feign-helloworld/target/classes/codes/walery/research/feign/wikidata/WikidataRunner.class]:   通过构造函数参数表示不满意的依赖关系   类型为[codes.walery.research.feign.wikidata.WikidataClient]的索引0:   :没有类型的限定bean   找到[codes.walery.research.feign.wikidata.WikidataClient]   依赖:预计至少有1个bean有资格成为autowire   这种依赖的候选人。依赖注释:{};嵌套   例外是   org.springframework.beans.factory.NoSuchBeanDefinitionException:没有   合格的bean类型   找到[codes.walery.research.feign.wikidata.WikidataClient]   依赖性:预期至少1次被引发:   org.springframework.beans.factory.NoSuchBeanDefinitionException:没有   合格的bean类型   找到[codes.walery.research.feign.wikidata.WikidataClient]   依赖:预计至少有1个bean有资格成为autowire   这种依赖的候选人。依赖注释:{} at   org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1326)   有资格作为此依赖关系的autowire候选者。   依赖注释:{} at   org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1072)     在   org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)   〜[spring-beans-4.2.1.RELEASE.jar:4.2.1.RELEASE] at   org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:967)     在   org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813)     在   org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:185)   〜[spring-beans-4.2.1.RELEASE.jar:4.2.1.RELEASE] at   org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)     在   org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1143)   〜[spring-beans-4.2.1.RELEASE.jar:4.2.1.RELEASE] ... 18更多   org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1046)   〜[spring-beans-4.2.1.RELEASE.jar:4.2.1.RELEASE] at   org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)   〜[spring-beans-4.2.1.RELEASE.jar:4.2.1.RELEASE] at   org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)   〜[spring-beans-4.2.1.RELEASE.jar:4.2.1.RELEASE] at   org.springframework.beans.factory.support.AbstractBeanFactory $ 1.getObject(AbstractBeanFactory.java:305)   〜[spring-beans-4.2.1.RELEASE.jar:4.2.1.RELEASE] at   org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)   〜[spring-beans-4.2.1.RELEASE.jar:4.2.1.RELEASE] at   org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301)   〜[spring-beans-4.2.1.RELEASE.jar:4.2.1.RELEASE] at   org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196)   〜[spring-beans-4.2.1.RELEASE.jar:4.2.1.RELEASE] at   org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)   〜[spring-beans-4.2.1.RELEASE.jar:4.2.1.RELEASE] at   org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:834)   〜[spring-context-4.2.1.RELEASE.jar:4.2.1.RELEASE] at   org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537)   〜[spring-context-4.2.1.RELEASE.jar:4.2.1.RELEASE] at   org.springframework.boot.SpringApplication.refresh(SpringApplication.java:667)   [spring-boot-1.3.0.M5.jar:1.3.0.M5] at   org.springframework.boot.SpringApplication.doRun(SpringApplication.java:342)   [spring-boot-1.3.0.M5.jar:1.3.0.M5] at   org.springframework.boot.SpringApplication.run(SpringApplication.java:273)   [spring-boot-1.3.0.M5.jar:1.3.0.M5] at   org.springframework.boot.SpringApplication.run(SpringApplication.java:980)   [spring-boot-1.3.0.M5.jar:1.3.0.M5] at   org.springframework.boot.SpringApplication.run(SpringApplication.java:969)   [spring-boot-1.3.0.M5.jar:1.3.0.M5] at   codes.walery.research.feign.FeignHelloworldApplication.main(FeignHelloworldApplication.java:12)   [课程/:na] 2017-07-19 08:02:29.059 INFO 2018 --- [Thread-1]   s.c.a.AnnotationConfigApplicationContext:结束   org.springframework.context.annotation.AnnotationConfigApplicationContext@3d8314f0:   启动日期[Wed Jul 19 08:02:24 CEST 2017];背景的根源   层次结构

     

使用退出代码1完成处理

我不肯否认自己是Spring and Feign的新手。事情是我需要拼命地解决这两个问题。到目前为止,我已经花费了10多个小时来研究Feign,但没有成功。

请求帮助和指导

MissingBracket

1 个答案:

答案 0 :(得分:-2)

您的代码有几个问题,一个是直接致命的,另一个是代码味道。如果你声称自己是以Spring为起点,那么IMO就会过度热衷于Spring Cloud。你需要很多帮助。

我在GitHub上使用Feign客户端完成了一个完整的应用程序。它也使用Hystrix,但您可以忽略它以达到您的目的。我打算写一篇关于它的博客文章,只是还没有这样做。我的Eureka blog post是互联网上关于Netflix Eureka最受欢迎的资源之一。

  1. 您不应该将网址放在Feign客户端中;假冒客户端是一种抽象。您可以为其命名并在其他位置配置属性。 [代码味]

  2. 您不应该在Feign客户端中对查询参数进行硬编码。 [代码味]

  3. 您不需要Feign.builder(); Spring将为您自动配置一个。如果有些东西无法使用注释或Feign配置进行配置,则只需要它。 [我不确定这种行为]

  4. 你需要EnableFeignClients让Spring接听客户端,假设它在CommandLineRunner的同一个或一个子包中。就像你承认的那样,你显然对Spring不太了解,否则你不会成为@Component。阅读有关如何实施CommandLineRunner。[致命]

  5. 的信息

    看看我的示例应用。顺便说一下,10个小时什么都不是;我已经使用Spring Cloud工作了1。5年,我仍然不知道所有这些。