SpringCloud实战5 - 使用Feign实现声明式rest调用

   上一节是是使用RestTemplate实现REST API调用的,大致代码如下:

   

@RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String hello(@RequestParam String name) {
        ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://provider/hello?name={1}", String.class,name);
        return responseEntity.getBody();
    }

   由代码可知,我们是使用拼接字符串的方式构造url的,改url只有一个参数,然后在现实中,我们往往有很多的参数,如果还使用这种方式,那么就会变的很低效。并且难为维护。

   Feign简介   

   在springcloud中,使用feign非常简单,创建一个接口,并在接口上添加一些注解,代码就完成了,feign支持多种注解。Springcloud对feign进行了强化,是feign支持了springmvc注解,并整合了Ribbon和eureka,从而让feign的使用更方便。

   为服务消费者整合Feign

      创建一个子模块,在子模块的pom.xml里添加如下依赖:

   

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>

   创建一个feign接口,并添加@FeignClient注解   

@FeignClient(name = "provider")
public interface TestFeignClient {

    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    String hello(@RequestParam("name") String name);
}

   @FeignClient注解中的provider是一个任意的客户端的名称,用于创建Ribbon负载均衡。

   创建controller代码

@RestController
@RequestMapping(value = "feign")
public class HelloController {

    @Autowired
    TestFeignClient testFeignClient;
    @Autowired
    private LoadBalancerClient loadBalancerClient;

    @GetMapping(value = "/hello")
    public String hello(@RequestParam String name) {
        String str = testFeignClient.hello(name);
        return str;
    }

    @GetMapping("/log-user-instance")
    public void logUserInstance() {
        ServiceInstance serviceInstance = this.loadBalancerClient.choose("provider");
        // 打印当前选择的是哪个节点
        System.out.println("{}:{}:{}," + serviceInstance.getServiceId()+","+ serviceInstance.getHost()+","+ serviceInstance.getPort());
    }
}

 添加启动类代码:

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients //注解表示开启Spring Cloud Feign的支持功能
public class YmkFeignConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(YmkFeignConsumerApplication.class, args);
    }
}

   以此启动服务,多次访问:http://localhost:8010/feign/hello?name=feign 返回结果如下

   

   看下提供者服务器其控制台打印结果,已经实现了负载均衡。

  

    扩展阅读:feign传递多参数  https://www.jianshu.com/p/7ce46c0ebe9d 

   自定义配置Feign

       feign的自定义配置同样支持java代码跟属性配置。

    Feign对继承的支持

    Feign支持继承,使用继承,可将一些公共的操作分组到一些父接口中,从而简化Feign的开发,下面展示了简单的例子。

   在api接口项目中,创建一个接口

public interface TestService {

    @RequestMapping(value = "/hello2", method = RequestMethod.GET)
    String hello(@RequestParam("name") String name);
}

   在服务提供者中实现接口

@RestController
public class TestController2 implements TestService {

    @RequestMapping(value = "/hello2", method = RequestMethod.GET)
    public String hello(String name) {
        System.out.println("Hello2 "+name);
        return "Hello2 "+name;
    }
}

服务消费者中,新建一个接口并继承api中的接口

@FeignClient(name = "provider")
public interface TestFeignClient2 extends TestService {

}

 创建一个新的controller,用此接口即可

  

@RestController
@RequestMapping(value = "feign2")
public class HelloController2 {

    @Autowired
    TestFeignClient2 testFeignClient2;
    @Autowired
    private LoadBalancerClient loadBalancerClient;

    @GetMapping(value = "/hello2")
    public String hello(@RequestParam String name) {
        String str = testFeignClient2.hello(name);
        return str;
    }

    @GetMapping("/log-user-instance2")
    public void logUserInstance() {
        ServiceInstance serviceInstance = this.loadBalancerClient.choose("provider");
        // 打印当前选择的是哪个节点
        System.out.println("{}:{}:{}," + serviceInstance.getServiceId()+","+ serviceInstance.getHost()+","+ serviceInstance.getPort());
    }
}

   在启动类添加接口路径,防止出现接口无法注入的问题。

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients("com.yang.test.ymkfeignconsumer.feign") //注解表示开启Spring Cloud Feign的支持功能,指定接口路径,防止出现无法注入的问题
public class YmkFeignConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(YmkFeignConsumerApplication.class, args);
    }
}

   依次启动服务,访问 :http://localhost:8010/feign2/hello2?name=feign2 

    

   注意: 尽管Feign的继承可帮助我们进一步简化Feign的开发,但SpringCloud官方并不建议在提供者跟消费者之间共享接口。因为这种方式造成了提供者跟消费者之间的紧耦合。

   秉承这种思想:将我们的项目重新划分了一下,除了继承的接口在api项目中,其他的接口放在消费者端。具体见博客底部的源码!

   配置日志级别

   很多场景下,需要了解feign的具体细节,Feign对日志的处理非常灵活,可以为每个feign客户端指定日记记录策略。

   我们可以为每个Feign客户度配置各自的logger.Level对象。

   NONE 不输出日志

   BASIC 只有请求方法、URL、响应状态代码、执行时间

   HEADERS基本信息以及请求和响应头

   FULL 请求和响应 的heads、body、metadata,建议使用这个级别。

   创建一个配置类,此类一定要让spring可以扫描到

@Configuration
public class FeignLogConfiguration {
  @Bean
  Logger.Level feignLoggerLevel() {
    return Logger.Level.FULL;
  }
}

   修改feign接口,指定配置类

@FeignClient(name = "provider" ,configuration = FeignLogConfiguration.class)
public interface TestFeignClient {

    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    String hello(@RequestParam("name") String name);
}

修改application.yml文件


logging:
  level:
    com.yang.test.ymkfeignconsumer.feign.TestFeignClient: debug
 # 将Feign接口的日志级别设置成DEBUG,因为Feign的Logger.Level只对DEBUG作出响应。

一次启动项目,访问: http://localhost:8010/feign/hello?name=feign

      

日志打印成功。

 

源码下载 :  https://download.csdn.net/download/u013083284/10755394

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值