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,然後訪問相應的介面,測試結果如下: