美文网首页
008--Feign是什么鬼?

008--Feign是什么鬼?

作者: 糖纸疯了 | 来源:发表于2018-04-22 16:06 被阅读147次

    Feign是一个web请求的工具,可以将请求指定到具体的服务上去

    话题1:什么是Feign ?

    Feign 是一个声明web服务客户端,这使得编写web服务客户端更容易

    • 可使用Feign 创建一个接口并对它进行注解
    • 可插拔的注解支持包括Feign注解与JAX-RS注解
    • Feign还支持可插拔的编码器与解码器,
    • Spring Cloud 增加了对 Spring MVC的注解,Spring Web 默认使用了HttpMessageConverters,
    • Spring Cloud 集成 Ribbon 和 Eureka 提供的负载均衡的HTTP客户端 Feign.

    话题2:name和url的关系:

    • 不写url时:name就是调用的服务的名称
    • 编写url时:name就是url指定服务的别名(现在版本声明:不能单独写url,name必须写)
    @FeignClient(name = "xxxx", url = "http://localhost:8761/", configuration = MyFeignConfiguration2.class)
    

    话题3:如何使用Feign?

    • 3.1 引入Feigon的Jar包
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-feign</artifactId>
    </dependency>
    
    • 3.2 创建接口,指定要调用的服务名称
    @FeignClient("server-provider")
    public interface ConsumeFeign {
       @RequestMapping(value = "/simple/{id}", method = RequestMethod.GET)
       public User findById(@PathVariable Long id);
    }
    
    • 3.3 将方法的调用改成接口的实现
    @RestController
    public class ConsumeController {
        @Autowired
        private ConsumeFeign consumeFeign;
    
        @GetMapping("/movie/{id}")
        public User findById(@PathVariable Long id) {
            return this.consumeFeign.findById(id);
        }
    }
    
    • 3.4 在入口程序上添加@EnableFeignClients
    @SpringBootApplication
    @EnableEurekaClient
    @EnableFeignClients
    public class ServerConsumeFeigonApplication {
        @Bean
        public RestTemplate restTemplate() {
          return new RestTemplate();
        }
          
        public static void main(String[] args) {
            SpringApplication.run(ServerConsumeFeigonApplication.class, args);
        }
    }
    
    • 3.5 对比前后,请求方式发生的变化
    #以前使用RestTemplate对象去找对应的服务和请求方法
    @GetMapping("/movie/{id}")
    public User findById(@PathVariable Long id) {
          return this.restTemplate.getForObject("http://localhost:7911/simple/" + id, User.class);
    }
    
    #现在使用feign,去发现服务,然后映射到相关请求上
    @FeignClient("server-provider")
    public interface ConsumeFeign {
         @RequestMapping(value = "/simple/{id}", method = RequestMethod.GET)
         public User findById(@PathVariable("id") Long id); 
    }
    @GetMapping("/movie/{id}")
    public User findById(@PathVariable Long id) {
        return this.consumeFeign.findById(id);
    }
    

    话题4:使用Feign的三个坑?

    • 使用@GetMapping("/movie/{id}")标注不可以
    • 使用@PathVariable不添加@PathVariable("id")int id
    • 参数中传递复杂变量public User findByUser(User user) {},即使在controller上标记是GET请求,但是在Fegin上面的响应也是POST
    #不能使用,启动报错
    @GetMapping("/movie/{id}")
    public User findById(@PathVariable Long id) {
          return this.restTemplate.getForObject(this.userServicePath + id, User.class);
    }
    #可以使用,启动不报错
    @RequestMapping(value="/movie/{id}",method = RequestMethod.GET)
    public User findById2(@PathVariable("id") Long id) {
          return this.restTemplate.getForObject(this.userServicePath + id, User.class);
    }
    #不可以使用,运行报错
    @RequestMapping(value="/movie/{id}",method = RequestMethod.GET)
    public User findByUser(User user) {
          return this.restTemplate.getForObject(this.userServicePath + user.getId(), User.class);
    }
    

    话题5:使用Feign的自定义配置(feigon标注)

        SpringCloud根据FeignClientsConfiguration为每一个命名的客户端创建一个新的整体ApplicationContext.
        这包含(其他)feign Decoder,feigon Encoder和feign COntract
    

    也就是说:

    • 1.先创建一个ConsumeFeign接口,在里面实现我们自己的数据请求
    public interface ConsumeFeign {
          @RequestLine("GET /simple/{id}")
          public User findById(@Param("id") Long id);
    }
    
    • 2.创建自定义的FeignConfiguration
    public class MyFeignConfiguration {
        @Bean // Feign协议
        public Contract feignContract() {
            return new feign.Contract.Default();
        }
        @Bean // Feign日志等级
        Logger.Level feignLoggerLevel() {
            return Logger.Level.FULL;
        }
    }
    
    • 3.然后在接口中指明我们要请求的服务和使用的FeignConfiguration
    @FeignClient(name = "microservice-provider-user", configuration = MyFeignConfiguration.class)
    public interface ConsumeFeign {
        @RequestLine("GET /simple/{id}")
        public User findById(@Param("id") Long id);
    }
    
    • 4.最后调用相关的feign
    @GetMapping("/movie/{id}")
    public User findById(@PathVariable Long id) {
        return (User) this.consumeFeign.findById(id);
    }
    
    • 5.总结:调用服务的时候
      • 5.1、根据consumeFeign调用方法,
      • 5.2、使用Feign自带的标注@RequestLine("GET /simple/{id}")去@FeignClient中去找到相关的配置
      • 5.3、使用@FeignClient的配置去使用自定义Feign的Contract协议

    话题6:使用Feign的自定义配置(Spring标注)

    • 1.先创建一个ConsumeFeign接口,在里面实现我们自己的数据请求
    public interface ConsumeFeign2 {
      @RequestMapping(value = "/eureka/apps/{serviceName}")
      public String findServiceInfoFromEurekaByServiceName(@PathVariable("serviceName") String serviceName);
    }
    
    • 2.创建自定义的FeignConfiguration
    public class MyFeignConfiguration2 {
        @Bean
        public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
            return new BasicAuthRequestInterceptor("admin", "admin");
        }
    }
    
    • 3.然后在接口中指明我们要请求的服务和使用的FeignConfiguration
    @FeignClient(name = "xxxx", url = "http://localhost:8761/", configuration = MyFeignConfiguration2.class)
    public interface ConsumeFeign2 {
      @RequestMapping(value = "/eureka/apps/{serviceName}")
      public String findServiceInfoFromEurekaByServiceName(@PathVariable("serviceName") String serviceName);
    }
    
    • 4.最后调用相关的feign
    @GetMapping("/{serviceName}")
    public String findServiceInfoFromEurekaByServiceName(@PathVariable String serviceName) {
        return this.consumeFeign2.findServiceInfoFromEurekaByServiceName(serviceName);
    }
    
    • 5.总结:调用服务的时候
      • 5.1、根据consumeFeign2调用方法
      • 5.2、使用SpringCloud请求标注(已经实现了feign协议),直接去调用查找配置FeignConfiguration
      • 5.3、因为要访问Eureka,设置的有账户和密码,在FeignConfiguration中配置账户和密码

    相关文章

      网友评论

          本文标题:008--Feign是什么鬼?

          本文链接:https://www.haomeiwen.com/subject/mjwqlftx.html