Spring Cloud中使用Feign(十二)

首先还是需要去们的Spring Cloud服务管理框架Eureka简单示例(三)这篇博客底部拿到源码,这是一个最微型的集群。为了符合后面的测试,先把eureka-provider项目com.init.springCloud包下的ProviderApp类修改成按照端口启动:

package com.init.springCloud;

import java.util.Scanner;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient
public class ProviderApp {

	public static void main(String[] args) {
		@SuppressWarnings("resource")  
        Scanner scan = new Scanner(System.in);  
        String port = scan.nextLine();  
        new SpringApplicationBuilder(ProviderApp.class).properties("server.port=" + port).run(args);  
	}

}

接着为ProviderController控制器添加一个方法,用于返回简单的JSON字符串:

@RequestMapping(value = "/hello/{name}", method = RequestMethod.GET)
public String sayHello(@PathVariable String name){
	return "hello "+name+", I'm glad to see you.";
}

然后修改eureka-consumer项目的application.yml配置文件,将启动端口号修改为9090:

server:
  port: 9090

之后依次运行三个项目的**App类里面的main方法,启动三个项目。注意,eureka-provider项目需要在控制台输入端口号之后回车。之后访问:http://localhost:8761,http://localhost:8080/search/1,http://localhost:9090/router,看看是否都能正常调用。

引入Spring Cloud中的Feign

因为feign是用于服务调用端,做服务调用的,我们在eureka-consumer项目中引入它的依赖:


    org.springframework.cloud
    spring-cloud-starter-feign

然后开启feign,让eureka-consumer能够使用到feign提供的能力。找到ConsumerApp启动类,增加@EnableFeignClients的注解:

package com.init.springCloud;

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;

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class ConsumerApp {

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

}

然后,我们需要定义一个接口PersonClient,用做Feign处理请求调用:

package com.init.springCloud;

import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@FeignClient("eureka-provider")
public interface PersonClient {

	@RequestMapping(method = RequestMethod.GET, value = "/hello/{name}")
	String sayHello(@PathVariable("name") String name);
	
}

在接口上,我们使用了@FeignClient注解,表明需要请求的服务提供者的服务ID(ServiceId),然后在抽象方法上面用Spring提供的注解@RequestMapping,注明请求的方式和路径,参数也用Spring注解@PathVariable修饰(注意需要把参数名称填进去),Feign内部有专门的SpringMvcContract注解解释器(这个注解解释器可以查看OpenFeign之feign使用简介(十一))来理解Spring的@RequestMapping注解,所以在这里使用Spring的注解来替代feign提供的@RequestLine,让我们回归到了熟悉的配置上,简化了开发难度。

接下来就是重新编写ConsumerController控制器,注入我们刚刚编写的PersonClient接口:

package com.init.springCloud;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class ConsumerController {
	
	@Autowired PersonClient PersonClient;
	
	@RequestMapping(method = RequestMethod.GET, value = "/router/{name}", 
			produces = MediaType.APPLICATION_JSON_VALUE)
	public String router(@PathVariable String name){
		return PersonClient.sayHello(name);
	}
	
}

重新启动eureka-consumer项目,访问:http://localhost:9090/router/spirit,浏览器能正常返回我们的字符串,就说明我们编写的Feign客户端运行正常

Spring Cloud中使用Feign(十二)_第1张图片

Feign的负载均衡效果

基于Ribbon,Feign也拥有负载均衡的效果(不用再引入Ribbon依赖)。

修改eureka-provider的Person实体类,新增一个属性,用端口来确认访问的哪一个服务:

package com.init.springCloud;

import lombok.Data;

@Data
public class Person {

	private Integer id;			//主键ID
	private String name;		//姓名
	private String info;		//url路径信息
	
}

然后修改ProviderController控制器,通过请求获取这个url信息:

@RequestMapping(value = "/search/{id}", method = RequestMethod.GET, 
		produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public Person searchPerson(@PathVariable Integer id, HttpServletRequest request){
	Person person = new Person();
	person.setId(id);
	person.setName("Spirit");
	person.setInfo(request.getRequestURL().toString());  
	return person;
}

启动两个eureka-provider项目,端口分别是8080和8081。

然后拷贝eureka-provider项目的Person实体到eureka-consumer中(lombok需要引入相关依赖,也可以改写成自己生成getter、setter方法),在PersonClient接口中新增方法,用于返回这个实体:

@RequestMapping(method = RequestMethod.GET, value = "/search/{id}")
Person getPersonById(@PathVariable("id") Integer id);

然后在ConsumerController项目中新增方法,返回Person实体类的JSON字符串:

@RequestMapping(method = RequestMethod.GET, value = "/find/{id}", 
		produces = MediaType.APPLICATION_JSON_VALUE)
public Person getPersonById(@PathVariable Integer id){
	return PersonClient.getPersonById(id);
}

重启eureka-consumer项目,浏览器多次访问:http://localhost:9090/find/1,我们可以看到Feign实现了负载均衡的效果:

Spring Cloud中使用Feign(十二)_第2张图片

Spring Cloud中使用Feign(十二)_第3张图片

Feign提供的Bean组件

Spring Cloud Netflix在默认情况下提供了以下bean(Bean类型  Bean名称:类名):

 

  • Decoder feignDecoder: ResponseEntityDecoder (which wraps a SpringDecoder)
  • Encoder feignEncoder: SpringEncoder
  • Logger feignLogger: Slf4jLogger
  • Contract feignContract: SpringMvcContract
  • Feign.Builder feignBuilder: HystrixFeign.Builder
  • Client feignClient: if Ribbon is enabled it is a LoadBalancerFeignClient, otherwise the default feign client is used.

我们可以通过设置feign.okhttp.enabled或者feign.httpclient.enabled属性为true来分别启用OkHttpClient和ApacheHttpClient的Feign客户端,然后分别在类路径中使用它们。

Spring Cloud Netflix在默认情况下不提供以下bean,但仍然从应用程序上下文中查找这些类型的bean,以创建feign客户端:

 

  • Logger.Level
  • Retryer
  • ErrorDecoder
  • Request.Options
  • Collection
  • SetterFactory

源码点击这里

最后,大家有什么不懂的或者其他需要交流的内容,也可以进入我的QQ讨论群一起讨论:654331206

Spring Cloud系列:

Spring Cloud介绍与环境搭建(一)

Spring Boot的简单使用(二)

Spring Cloud服务管理框架Eureka简单示例(三)

Spring Cloud服务管理框架Eureka项目集群(四)

Spring Cloud之Eureka客户端健康检测(五)

Netflix之第一个Ribbon程序(六)

Ribbon负载均衡器详细介绍(七)

Spring Cloud中使用Ribbon(八)

具有负载均衡功能的RestTemplate底层原理(九)

OpenFeign之第一个Feign程序(十)

OpenFeign之feign使用简介(十一)

Spring Cloud中使用Feign(十二)

Netflix之第一个Hystrix程序(十三)

Netflix之Hystrix详细分析(十四)

Spring Cloud中使用Hystrix(十五)

Netflix之第一个Zuul程序(十六)

Spring Cloud集群中使用Zuul(十七)

Netflix之Zuul的进阶应用(十八)

消息驱动之背景概述(十九)

消息中间件之RabbitMQ入门讲解(二十)

消息中间件之Kafka入门讲解(二十一)

Spring Cloud整合RabbitMQ或Kafka消息驱动(二十二)

你可能感兴趣的:(Spring,Cloud)