首页 > 代码库 > 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>
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服务