1. 程式人生 > >springcloud系列—Feign—第4章-2: Feign 的繼承特性

springcloud系列—Feign—第4章-2: Feign 的繼承特性

資料參考:《Spring Cloud 微服務實戰》

目錄

建立公共介面

服務提供者中實現介面

服務消費者中繼承介面


上篇文章我們瞭解了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>

建立需要的實體類,把之前用到的book實體類複製到這個api專案。

專案建立好之後,我們在這個專案中提供一個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

這裡寫圖片描述