前言:一般情况下我们通常使用RestTemplate来实现声明式远程调用,但是当参数过多,那么效率就会变得很低,并且难以维护,所以在微服务当中也有声明式Rest调用的组件Feign
一、Feign简介
Feign是Netflix开发的声明式、模板化的http客户端,Feign可以帮我们更加便捷、优雅地调用HTTP API。在SpringCloud中使用Feign非常简单,创建一个接口,并在接口上加上注解,就完成了声明式调用;
二、Feign与SpringCloud的整合简单使用
注:本次学习记录是基于之前的Eureka介绍和Ribbon介绍之上实践,这里只展示关键代码,其余代码可在代码示例中查看;
1、创建基于Eureka和Ribbon的服务端和两个客户端生产者、消费者:
Server:


xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.cn eureka-ribbon-server 1.0-SNAPSHOT UTF-8 1.8 org.springframework.boot spring-boot-starter-parent 1.5.13.RELEASE org.springframework.cloud spring-cloud-starter-eureka-server org.springframework.cloud spring-cloud-dependencies Edgware.SR3 pom import org.springframework.boot spring-boot-maven-plugin


server.port=8761 #注意:这两个配置eureka默认为true,要改成false,否则会报错,connot connect server #表示是否将自己注册在EurekaServer上 eureka.client.register-with-eureka=false #表示是否从EurekaServer获取注册信息 eureka.client.fetch-registry=false eureka.client.service-url.defaultZone=http://localhost:8761/eureka/


package com.cn; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; /** * @program: springcloud-example * @description: 启动类 * @author: * @create: 2018-06-15 15:43 **/ @SpringBootApplication @EnableEurekaServer public class ServerApplication { public static void main(String[] args) { SpringApplication.run(ServerApplication.class,args); } }
Client生产者:


xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.cn eureka-ribbon-client2 1.0-SNAPSHOT UTF-8 1.8 org.springframework.boot spring-boot-starter-parent 1.5.13.RELEASE org.springframework.cloud spring-cloud-starter-ribbon org.springframework.cloud spring-cloud-starter-eureka org.springframework.cloud spring-cloud-dependencies Edgware.SR3 pom import org.springframework.boot spring-boot-maven-plugin


server.port=8763 spring.application.name=client-87 eureka.client.service-url.defaultZone=http://localhost:8761/eureka


package com.cn; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; /** * @program: springcloud-example * @description: * @author: * @create: 2018-06-15 16:05 **/ @SpringBootApplication @EnableDiscoveryClient public class ClientApplication { public static void main(String[] args) { SpringApplication.run(ClientApplication.class, args); } }


package com.cn.contorller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ResponseBody; /** * @program: springcloud-example * @description: * @author: * @create: 2018-06-15 16:12 **/ @Controller public class ClientController { @GetMapping("/getUser") @ResponseBody public String getUser() { System.out.println("获取用户成功"); return "{\"username\":\"张三\",\"age\":\"10\"}"; } }
2、在消费者module中的maven依赖中添加相关依赖库,创建Feign访问接口,并注解,通过识别Eureka提供的应用名称,来找对应的请求路径:
pom.xml:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
com.cn
eureka-feign-client
1.0-SNAPSHOT
UTF-8
1.8
org.springframework.boot
spring-boot-starter-parent
1.5.13.RELEASE
org.springframework.cloud
spring-cloud-starter-ribbon
org.springframework.cloud
spring-cloud-starter-eureka
org.springframework.cloud
spring-cloud-starter-feign
org.springframework.cloud
spring-cloud-dependencies
Edgware.SR3
pom
import
org.springframework.boot
spring-boot-maven-plugin
application.properties:
server.port=8762 spring.application.name=client-8762 eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
Feign接口:
import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.RequestMapping; @FeignClient(name = "CLIENT-87") public interface UserFeign { @RequestMapping("/getUser") public String getUser(); }
FeignController:
package com.cn.controller;
import com.cn.feign.UserFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* @program: springcloud-example
* @description:
* @author:
* @create: 2018-06-15 15:55
**/
@RestController
public class FeignController {
@Autowired
private LoadBalancerClient loadBalancerClient;
@Autowired
private RestTemplate restTemplate;
@Autowired
private UserFeign userFeign;
@RequestMapping("/getUser")
public String getUser() {
return userFeign.getUser();
}
@GetMapping("/loadInstance")
public String loadInstance() {
ServiceInstance choose = this.loadBalancerClient.choose("client-87");
System.out.println(choose.getServiceId()+":"+choose.getHost()+":"+choose.getPort());
return choose.getServiceId() + ":" + choose.getHost() + ":" + choose.getPort();
}
}
在ClientApplication.java启动类中加入@EnableFeignClients注解:
package com.cn; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.netflix.feign.EnableFeignClients; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; /** * @program: springcloud-example * @description: * @author: * @create: 2018-06-15 15:51 **/ @SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class ClientApplication { public static void main(String[] args) { SpringApplication.run(ClientApplication.class, args); } /** * @Description: * @Param: * @return: * @Author: * @Date: 2018/6/15 */ @Bean @LoadBalanced public RestTemplate getRestTemplate() { return new RestTemplate(); } }
3、分别启动Server、Client生产者、Client消费者,并调用访问http://localhost:8761、http://localhost:8762/getUser,如图:
调用成功!
参考书籍:《SpringCloud与Docker微服务架构实战》周力著
代码示例:https://gitee.com/lfalex/springcloud-example( eureka-feign-client、 eureka-ribbon-server、 eureka-ribbon-client2这三个module)