Spring Cloud中聲明式服務調用Feign (11)

轉自 https://blog.csdn.net/u012702547/article/details/77823434

這個系列我感覺真的太好了,可以一步一步的瞭解spring cloud 的搭建以及更深層次的東西,對想學這門技術的朋友真的入門特別的快,感謝這位大哥的分享,我也會持續的更新過來。

-------------------------------------------------------------------------------------------------------------------------------------------------------------

前面幾篇文章我們詳細的介紹了Ribbon、RestTemplate、Hystrix組件,這些組件是我們Spring Cloud中非常基礎的組件,小夥伴們在使用的過程中可能也發現了這些東西都是同時出現的,而且配置也都非常相似,每次開發都有很多相同的代碼,因此,Spring Cloud基於Netflix Feign整合了Ribbon和Hystrix,讓我們的開發工作變得更加簡單,就像Spring Boot是對Spring+SpringMVC的簡化一樣。Spring Cloud Feign不僅在配置上大大簡化了開發工作,同時還提供了一種聲明式的Web服務客戶端定義方式。 

在前面幾篇文章中,我們爲了簡化RestTemplate操作,將之封裝在一個BookService中,但同時我們也發現BookService中的方法幾乎都是模板式的,寫起來很枯燥,Spring Cloud Feign對此進行了進一步的封裝,簡化了我們的封裝操作。接下來我們就來看看Spring Cloud Feign的使用。

本文是Spring Cloud系列的第十六篇文章,瞭解前十五篇文章內容有助於更好的理解本文:

1.使用Spring Cloud搭建服務註冊中心 
2.使用Spring Cloud搭建高可用服務註冊中心 
3.Spring Cloud中服務的發現與消費 
4.Eureka中的核心概念 
5.什麼是客戶端負載均衡 
6.Spring RestTemplate中幾種常見的請求方式 
7.RestTemplate的逆襲之路,從發送請求到負載均衡 
8.Spring Cloud中負載均衡器概覽 
9.Spring Cloud中的負載均衡策略 
10.Spring Cloud中的斷路器Hystrix 
11.Spring Cloud自定義Hystrix請求命令 
12.Spring Cloud中Hystrix的服務降級與異常處理 
13.Spring Cloud中Hystrix的請求緩存 
14.Spring Cloud中Hystrix的請求合併 
15.Spring Cloud中Hystrix儀表盤與Turbine集羣監控


Spring Cloud Feign入門

環境搭建

OK,首先我們通過下面六步來創建一個Spring Cloud Feign工程,先來體驗下Spring Cloud Feign帶給我們的便利。

第一步:創建普通Spring Boot工程

首先我們來創建一個普通的Spring Boot工程,取名爲feign-consumer。

第二步:添加依賴

這裏要添加的依賴主要是spring-cloud-starter-eureka和spring-cloud-starter-feign,如下:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.7.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
    <spring-cloud.version>Dalston.SR3</spring-cloud.version>
</properties>
<dependencies>
    <!-- 其他依賴 -->
    <!-- 自己添加的依賴 -->
    <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>
</dependencies>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

第三步:添加註解

然後在工程的入口類上添加@EnableFeignClients註解表示開啓Spring Cloud Feign的支持功能,如下:

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class FeignConsumerApplication {

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

第四步:聲明服務

定義一個HelloService接口,通過@FeignClient註解來指定服務名進而綁定服務,然後再通過SpringMVC中提供的註解來綁定服務提供者提供的接口,如下:

@FeignClient("hello-service")
public interface HelloService {
    @RequestMapping("/hello")
    String hello();
}

這相當於綁定了一個名叫hello-service(這裏hello-service大小寫無所謂)的服務提供者提供的/hello接口。我們來看一下我服務提供者提供的接口,如下:

@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String hello() {
    return "hello";
}

第五步:Controller中調用服務

接着來創建一個Controller來調用上面的服務,如下:

@RestController
public class FeignConsumerController {
    @Autowired
    HelloService helloService;

    @RequestMapping("/hello")
    public String hello() {
        return helloService.hello();
    }
}

第六步:屬性配置

最後,我們需要在application.properties中指定服務註冊中心,並配置端口號等,如下:

spring.application.name=feign-consumer
server.port=2005
eureka.client.service-url.defaultZone=http://localhost:1111/eureka/

測試

做完上面的操作之後,依次啓動eureka-server、provider和feign-consumer,然後訪問如下地址:http://localhost:2005/hello,訪問結果如下:

這裏寫圖片描述

Ribbon和Hystrix的功能都有,只是我們使用Feign實現起來更簡單,Feign使用了一種更加優雅的方式來調用服務提供者的接口,避免了我們寫模板式的RestTemplate代碼。

參數傳遞

上面我們看了一個簡單的調用案例,這個例子中沒有涉及到參數的傳遞,那麼接下來我們就來看看參數的傳遞要如何實現。

首先我先給我的服務提供者添加三個測試接口,如下:

@RequestMapping(value = "/hello1", method = RequestMethod.GET)
public String hello1(@RequestParam String name) {
    return "hello " + name + "!";
}

@RequestMapping(value = "/hello2", method = RequestMethod.GET)
public Book hello2(@RequestHeader String name, @RequestHeader String author, @RequestHeader Integer price) throws UnsupportedEncodingException {
    Book book = new Book();
    book.setName(URLDecoder.decode(name,"UTF-8"));
    book.setAuthor(URLDecoder.decode(author,"UTF-8"));
    book.setPrice(price);
    System.out.println(book);
    return book;
}

@RequestMapping(value = "/hello3", method = RequestMethod.POST)
public String hello3(@RequestBody Book book) {
    return "書名爲:" + book.getName() + ";作者爲:" + book.getAuthor();
}

hello1接口主要是接收一個String類型的參數,參數通過key-value的形式傳來,然後返回一個String類型的數據;hello2接口接收到參數攜帶在請求頭中,請求頭中傳遞中文會亂碼,所以要先編碼,再解碼(當然如果傳遞的是英文就不用這麼麻煩),然後返回一個Book對象;hello3則接收一個Book對象,返回一個字符串。

測試接口寫好之後,我們再來看看feign-consumer工程中的HelloService接口要怎麼寫,如下:

@FeignClient("hello-service")
public interface HelloService {
    @RequestMapping("/hello")
    String hello();

    @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);

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

這裏有一個細節需要小夥伴們注意,在SpringMVC中,@RequestParam和@RequestHeader註解,如果我們不指定value,則默認採用參數的名字作爲其value,但是在Feign中,這個value必須明確指定,否則會報錯。

最後添加測試接口,如下:

@RestController
public class FeignConsumerController {
    @Autowired
    HelloService helloService;

    @RequestMapping("/hello")
    public String hello() {
        return helloService.hello();
    }

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

    @RequestMapping(value = "/hello2")
    public Book hello2() throws UnsupportedEncodingException {
        Book book = helloService.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 helloService.hello(book);
    }
}

運行結果如下:

http://localhost:2005/hello1

這裏寫圖片描述

http://localhost:2005/hello2

這裏寫圖片描述

http://localhost:2005/hello3

這裏寫圖片描述

OK,關於Feign入門我們就先說到這裏,有問題歡迎留言討論。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章