首页 > 代码库 > Spring Cloud 入门教程(六): 用声明式REST客户端Feign调用远端HTTP服务

Spring Cloud 入门教程(六): 用声明式REST客户端Feign调用远端HTTP服务

首先简单解释一下什么是声明式实现?

要做一件事, 需要知道三个要素,where, what, how。即在哪里( where)用什么办法(how)做什么(what)。什么时候做(when)我们纳入how的范畴。

1)编程式实现: 每一个要素(where,what,how)都需要用具体代码实现来表示。传统的方式一般都是编程式实现,业务开发者需要关心每一处逻辑

2)声明式实现: 只需要声明在哪里(where )做什么(what),而无需关心如何实现(how)。Spring的AOP就是一种声明式实现,比如网站检查是否登录,开发页面逻辑的时候,只需要通过AOP配置声明加载页面(where)需要做检查用户是否登录(what),而无需关心如何检查用户是否登录(how)。如何检查这个逻辑由AOP机制去实现, 而AOP的登录检查实现机制与正在开发页面的逻辑本身是无关的。

在Spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端。Feign就是Spring Cloud提供的一种声明式REST客户端。可以通过Feign访问调用远端微服务提供的REST接口。现在我们就用Feign来调用SERVICE-HELLOWORLD暴露的REST接口,以获取到“Hello World”信息。在使用Feign时,Spring Cloud集成了Ribbon和Eureka来提供HTTP客户端的负载均衡。

下面我们就采用Feign的方式来调用Hello World服务集群。

1. 创建Maven工程,加入spring-cloud-starter-feign依赖

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

完整的pom文件如下:

技术分享
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 
 3         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 4         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <modelVersion>4.0.0</modelVersion>
 6     <groupId>com.chry</groupId>
 7     <artifactId>springcloud.helloworld.feign.client</artifactId>
 8     <version>0.0.1-SNAPSHOT</version>
 9     <packaging>jar</packaging>
10     <name>springcloud.helloworld.feign.client</name>
11     <description>Demo Feigh client application</description>
12 
13     <parent>
14         <groupId>org.springframework.boot</groupId>
15         <artifactId>spring-boot-starter-parent</artifactId>
16         <version>1.5.3.RELEASE</version>
17         <relativePath/> <!-- lookup parent from repository -->
18     </parent>
19 
20     <properties>
21         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
22         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
23         <java.version>1.8</java.version>
24     </properties>
25 
26     <dependencies>
27         <dependency>
28             <groupId>org.springframework.cloud</groupId>
29             <artifactId>spring-cloud-starter-eureka</artifactId>
30         </dependency>
31         <dependency>
32             <groupId>org.springframework.cloud</groupId>
33             <artifactId>spring-cloud-starter-feign</artifactId>
34         </dependency>
35         <dependency>
36             <groupId>org.springframework.boot</groupId>
37             <artifactId>spring-boot-starter-web</artifactId>
38         </dependency>
39 
40         <dependency>
41             <groupId>org.springframework.boot</groupId>
42             <artifactId>spring-boot-starter-test</artifactId>
43             <scope>test</scope>
44         </dependency>
45     </dependencies>
46 
47     <dependencyManagement>
48         <dependencies>
49             <dependency>
50                 <groupId>org.springframework.cloud</groupId>
51                 <artifactId>spring-cloud-dependencies</artifactId>
52                 <version>Dalston.RC1</version>
53                 <type>pom</type>
54                 <scope>import</scope>
55             </dependency>
56         </dependencies>
57     </dependencyManagement>
58 
59     <build>
60         <plugins>
61             <plugin>
62                 <groupId>org.springframework.boot</groupId>
63                 <artifactId>spring-boot-maven-plugin</artifactId>
64             </plugin>
65         </plugins>
66     </build>
67 
68     <repositories>
69         <repository>
70             <id>spring-milestones</id>
71             <name>Spring Milestones</name>
72             <url>https://repo.spring.io/milestone</url>
73             <snapshots>
74                 <enabled>false</enabled>
75             </snapshots>
76         </repository>
77     </repositories>
78 </project>
pom.xml

2. 创建启动类,需呀加上@EnableFeignClients注解以使用Feign, 使用@EnableDiscoveryClient开启服务自动发现

 1 package springcloud.helloworld.feign.service;
 2 
 3 import org.springframework.boot.SpringApplication;
 4 import org.springframework.boot.autoconfigure.SpringBootApplication;
 5 import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
 6 import org.springframework.cloud.netflix.feign.EnableFeignClients;
 7 
 8 @SpringBootApplication
 9 @EnableDiscoveryClient
10 @EnableFeignClients
11 public class ServiceFeignApplication {
12     public static void main(String[] args) {
13         SpringApplication.run(ServiceFeignApplication.class, args);
14     }
15 }

3. 添加配置文件application.yml, 使用端口8902, 名字定义为service-feign, 并注册到eureka服务中心

1 eureka:
2    client:
3       serviceUrl:
4         defaultZone: http://localhost:8761/eureka/
5 server:
6    port: 8902
7 spring:
8    application:
9       name: service-feign

4. 用@FeignClient注解定义一个feign接口类, 该接口通过value定义了需要调用的SERVICE-HELLOWORLD服务(通过服务中心自动发现机制会定位具体URL)。定义了一个接口方法sayHello(), 该方法通过@RequestMapping映射到SERVICE-HELLOWORLD提供的http://localhost:8762/

 1 package springcloud.helloworld.feign.service;
 2 
 3 import org.springframework.cloud.netflix.feign.FeignClient;
 4 import org.springframework.web.bind.annotation.RequestMapping;
 5 import org.springframework.web.bind.annotation.RequestMethod;
 6 
 7 @FeignClient(value = "http://www.mamicode.com/SERVICE-HELLOWORLD")
 8 public interface HelloWorldService {
 9     @RequestMapping(value = "http://www.mamicode.com/",method = RequestMethod.GET)
10     String sayHello();
11 }

5. 定义一个WebController。

注入之前通过@FeignClient定义生成的bean, 

sayHello()映射到http://localhost:8902/hello, 在这里,我修改了Hello World服务的映射,将根“/”, 修改成了“/hello”。

 1 package springcloud.helloworld.feign.service;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.web.bind.annotation.RequestMapping;
 5 import org.springframework.web.bind.annotation.RequestMethod;
 6 import org.springframework.web.bind.annotation.RestController;
 7 
 8 @RestController
 9 public class WebController {
10     @Autowired HelloWorldService helloWorldFeignService;
11     @RequestMapping(value = "http://www.mamicode.com/hello",method = RequestMethod.GET)
12     public String sayHello(){
13         return helloWorldFeignService.sayHello();
14     }
15 }

6. 启动Feign应用, 访问http://localhost:8902/hello, 多次刷新,可以看到和前一章Ribbon里面的应用一样, 两个Hello World服务的输出交替出现。说明通过Feign访问服务, Spring Cloud已经缺省使用了Ribbon负载均衡。

技术分享                技术分享

上一篇:Spring Cloud 入门教程(五): Ribbon实现客户端的负载均衡

下一篇: 

参考资料: http://blog.csdn.net/neosmith/article/details/52449921

                     http://blog.csdn.net/forezp/article/details/69808079

                     http://projects.spring.io/spring-cloud/spring-cloud.html#spring-cloud-feign

Spring Cloud 入门教程(六): 用声明式REST客户端Feign调用远端HTTP服务