专栏首页玩转JavaEESpring Cloud中Feign的继承特性

Spring Cloud中Feign的继承特性

上篇文章我们了解了Feign的基本使用,在HelloService类中声明接口时,我们发现这里的代码可以直接从服务提供者的Controller中复制过来,这些可以复制的代码Spring Cloud Feign对它进行了进一步的抽象,这里就用到了Feign的继承特性,本文我们就来看看如何利用Feign的继承特性来进一步简化我们的代码。


创建公共接口

首先我们来创建一个普通的maven工程,叫做hello-service-api,由于我们要在这一个项目中使用SpringMVC的注解,因此创建成功之后,需要添加spring-boot-starter-web依赖,如下:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.sang</groupId>
    <artifactId>commons</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

commons是我的另外一个maven项目,里边提供了Book这个类,因为我的hello-service-api一会要用到Book类,当然这里你也可以直接在hello-service-api中定义一个Book类。

项目创建好之后,我们在这个项目中提供一个HelloSerivce接口,如下:

@RequestMapping("/hs2")
public interface HelloService {
    @RequestMapping(value = "/hello1", method = RequestMethod.GET)
    String hello(@RequestParam("name") String name);

    @RequestMapping(value = "/hello2", method = RequestMethod.GET)
    Book hello(@RequestHeader("name") String name, @RequestHeader("author") String author, @RequestHeader("price") Integer price) throws UnsupportedEncodingException;

    @RequestMapping(value = "/hello3", method = RequestMethod.POST)
    String hello(@RequestBody Book book);
}

小伙伴们有木有觉得眼熟呢?就是我们上文在HelloService中定义的内容。为了和上文的HelloService进行区分,这次我做了请求窄化,给请求定义了前缀/hs2。

服务提供者中实现接口

hello-service-api工程写好之后,我们在服务提供者中添加对hello-service-api工程的依赖,如下:

<dependency>
    <groupId>org.sang</groupId>
    <artifactId>hello-service-api</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

然后在服务提供者中创建BookController2实现HelloService接口,如下:

@RestController
public class BookController2 implements HelloService {
    @Override
    public String hello(@RequestParam("name") String name) {
        return "hello " + name + "!";
    }

    @Override
    public Book hello(@RequestHeader("name") String name, @RequestHeader("author") String author, @RequestHeader("price") Integer price) throws UnsupportedEncodingException {
        org.sang.Book book = new org.sang.Book();
        book.setName(URLDecoder.decode(name,"UTF-8"));
        book.setAuthor(URLDecoder.decode(author,"UTF-8"));
        book.setPrice(price);
        System.out.println(book);
        return book;
    }

    @Override
    public String hello(@RequestBody Book book) {
        return "书名为:" + book.getName() + ";作者为:" + book.getAuthor();
    }
}

实现了HelloService接口当然就要实现HelloService接口中的方法,方法的实现还是和上文的一样。不同的是我这里不需要在方法上面添加@RequestMapping注解,这些注解在父接口中都有,不过在Controller上还是要添加@RestController注解,另外需要注意的是,方法中的参数@RequestHeader和@RequestBody注解还是要添加,@RequestParam注解可以不添加。

服务消费者中继承接口

写完了服务提供者之后,接下来我们再来看看服务消费者。首先在服务消费者中添加对hello-service-api的依赖,然后新建一个HelloService2类继承hello-service-api中的HelloService接口,如下:

@FeignClient("hello-service")
public interface HelloService2 extends HelloService {
}

这个接口中不需要添加任何方法,方法都在父接口中,这里只需要在类上面添加@FeignClient(“hello-service”)注解来绑定服务即可。

然后在Controller中提供相应的测试接口,如下:

@RestController
public class FeignConsumerController {

    @Autowired
    HelloService2 helloService2;

    @RequestMapping("/hello1")
    public String hello1() {
        return helloService2.hello("张三");
    }

    @RequestMapping(value = "/hello2")
    public Book hello2() throws UnsupportedEncodingException {
        Book book = helloService2.hello(URLEncoder.encode("三国演义","UTF-8"), URLEncoder.encode("罗贯中","UTF-8"), 33);
        System.out.println(book);
        return book;
    }

    @RequestMapping("/hello3")
    public String hello3() {
        Book book = new Book();
        book.setName("红楼梦");
        book.setPrice(44);
        book.setAuthor("曹雪芹");
        return helloService2.hello(book);
    }
}

测试

最后,我们依次启动eureka-server、provider和feign-consumer,然后访问相应的接口,测试结果如下:

http://localhost:2005/hello1:

http://localhost:2005/hello2:

http://localhost:2005/hello3:

总结

OK,通过上面的介绍小伙伴们应该已经体会到了Feign继承特性的方便之处了,这种方式用起来确实很方面,但是也带来一个问题,就是服务提供者和服务消费者的耦合度太高,此时如果服务提供者修改了一个接口的定义,服务消费者可能也得跟着变化,进而带来很多未知的工作量,因此小伙伴们在使用继承特性的时候,要慎重考虑。

关于Spring Cloud中Feign继承特性我们就介绍到这里,有问题欢迎留言讨论。

本文分享自微信公众号 - 玩转JavaEE(gh_d1ca11234a30),作者:悟空

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-10-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Spring Cloud中声明式服务调用Feign

    前面几篇文章我们详细的介绍了Ribbon、RestTemplate、Hystrix组件,这些组件是我们Spring Cloud中非常基础的组件,小伙伴们在使用的...

    江南一点雨
  • Spring Cloud中Feign配置详解

    到目前为止,小伙伴们对Feign的使用已经掌握的差不多了,我们在前文也提到Feign是对Ribbon和Hystrix的整合,那么在Feign中,我们要如何配置R...

    江南一点雨
  • 松哥手把手教你入门 Spring Boot + CAS 单点登录

    在微服务以及分布式系统中,单点登录变得越来越普遍,松哥之前也有两篇文章和大家介绍过单点登录的方案:

    江南一点雨
  • autoconf/automake最快速使用

    automake工具会根据config.in中的参量把Makefile.am转换成Makefile.in文件。在使用Automake之前,要先手动建立Makef...

    十毛
  • NetApp F3220 存储相关获取直连端口信息

            有时候可能我们的网络、路由、交换在前期已经部署完成,而由于没有标准化作业,故网络管理的不够完善,会存在无网络拓扑图的情况,这时候我们需要自己会绘...

    木子-Lee
  • 如何正确的将数组转换为ArrayList?

    对于不可变集合,你可以使用ImmutableList类及其of()与copyOf()工厂方法:(参数不能为空)

    崔笑颜
  • Spark——底层操作RDD,基于内存处理数据的计算引擎

    Apache Spark是一个快速的通用集群计算框架 / 殷勤。它提供Java,Scala,Python和R中的高级API,以及支持常规执行图的优化引擎。它还支...

    时间静止不是简史
  • java spark-streaming接收TCP/Kafka数据

     本文将展示 1、如何使用spark-streaming接入TCP数据并进行过滤; 2、如何使用spark-streaming接入TCP数据并进行wordcou...

    用户1225216
  • Java开发者易犯错误Top10

    Arrays.asList()将返回一个数组内部是私有静态类的ArrayList,这不是java.util.ArrayList类,java.util.Array...

    lyb-geek
  • Java微信公众平台开发_05_微信网页授权

    登录微信公众平台后台, 开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息 - 修改,

    shirayner

扫码关注云+社区

领取腾讯云代金券