Spring Cloud 对 Feign 进行了封装,集成了 Ribbon 并结合 Eureka 可以实现客户端的负载均衡,Spring Cloud 实现的 Feign 客户端类名为 LoadBalancerFeignClient,在该类中,维护着与 SpringClientFactory 相关的实例,通过SpringClientFactory 可以获取负载均衡器,负载均衡器会根据一定的规则来选取处理请求的服务器,最终实现负载均衡功能。
集成了 Hystrix 增加了服务容错处理,并为 Feign 的使用提供了各种默认属性,例如编码器、解码器、日志、注解翻译器、实例创建者和客户端,我们可以简单的使用 Feign,也可以增加自定义的配置。
下面给出基本的使用示例(不包含Hystrix):
1. 创建一个maven项目 servicefeign。
pom.xml文件配置如下,spring-cloud为Dalston版本;
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.springcloud.lcl</groupId>
<artifactId>service-feign</artifactId>
<version>1.0-SNAPSHOT</version>
<name>service-feign</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
<relativePath/>
</parent>
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
spring-cloud为Finchley版本的pom文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.springcloud.lcl.fetgn</groupId>
<artifactId>servicefeign_f</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>servicefeign_f</name>
<url>http://www.myorganization.org</url>
<build>
<finalName>servicefeign_f</finalName>
</build>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</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>
</project>
2. 项目目录结构及代码
启动类ServiceFeignApplication的代码:
package com.springcloud.lcl;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
/**
* Hello world!
*
*/
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class ServiceFeignApplication
{
public static void main( String[] args )
{
SpringApplication.run(ServiceFeignApplication.class,args);
}
}
api定义HiController类:
package com.springcloud.lcl.controller;
import com.springcloud.lcl.service.FeignHiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* @author lcl
* @version 0.1
* @date 2018/10/15
**/
@RestController
public class HiController {
@Autowired
FeignHiService feignHiService;
@RequestMapping(value = "/hi",method = RequestMethod.GET)
public String hi(@RequestParam String name){
return feignHiService.sayHiService(name);
}
}
service层 接口FeignHiService:
此处使用了FeignClient注解创建了调用service-hi服务的客户端,fallback指定了调用异常时的响应处理.
package com.springcloud.lcl.service;
import com.springcloud.lcl.service.impl.FeignHiServiceImpl;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(value = "service-hi",fallback = FeignHiServiceImpl.class)
public interface FeignHiService {
@RequestMapping(value = "/hi",method = RequestMethod.GET)
String sayHiService(@RequestParam(value = "name") String name);
}
实现类FeignHiServiceImpl:
package com.springcloud.lcl.service.impl;
import com.springcloud.lcl.service.FeignHiService;
import org.springframework.stereotype.Component;
/**
* @author lcl
* @version 0.1
* @date 2018/10/15
**/
@Component
public class FeignHiServiceImpl implements FeignHiService {
@Override
public String sayHiService(String name) {
return "HHii,"+name+",Sorry,Error....";
}
}
3. 配置文件application.properties(也可用yml方式) ;
spring.application.name=service-feign
server.port=8765
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
4. 启动及验证
启动eurekaserver,再依次启动servicehi,servicefeign;其中servicehi服务可修改端口号后再起一个实例(例:端口8763)
访问eureka http://localhost:8761/ 可看到如下,预期的几个服务已启动并注册;
访问service-feign提供的服务: http://localhost:8765/hi?name=name1
即可看到查询结果服务。