Feign是一个声明式客户端,可以实现服务间的相互调用。
今天代码实现一下Spring Cloud项目中,使用Feign来实现类似于昨天Ribbon调用其他服务接口的效果。
一、在服务中发布三个接口:
"/app") (publicStringadmin() { return"application-one:8005"; } "/admin") (publicStringadmin(Stringparam) { return"application-one:8005->"+param; } value="/customer", method=RequestMethod.POST, produces="application/json; charset=UTF-8") (publicStringcustomer(Customercustomer) { return"接收到客户对象->"+customer; }
确保这三个接口能正常访问,并且所属服务注册到Eureka Server。
贴出Customer代码:
publicclassCustomer { privateStringname; privateStringsex; publicCustomer() {} publicCustomer(Stringname, Stringsex) { this.name=name; this.sex=sex; } publicStringgetSex() { returnsex; } publicvoidsetSex(Stringsex) { this.sex=sex; } publicStringgetName() { returnname; } publicvoidsetName(Stringname) { this.name=name; } publicStringtoString() { return"Customer{name="+name+", sex="+sex+"}"; } }
二、搭建Feign项目
1.pom.xml
<dependencies><!--web组件--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--eurekaclient组件--><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-feign</artifactId><version>1.4.7.RELEASE</version></dependency></dependencies>
2.建立一个接口,使用@FeignClient注解引入对应服务的接口
packagecom.xing.study.cloud.feign; importcom.xing.study.cloud.entity.Customer; importorg.springframework.cloud.openfeign.FeignClient; importorg.springframework.web.bind.annotation.*; /*** @author rt*/value="application" ) ( publicinterfaceOneApplicationFeignClient { /*** application的app方法* @return str*/"/app") (Stringapp(); /*** application的app方法* @return str*/"/admin") (Stringadmin( ("param") Stringparam); /*** application的app方法* @return str*/value="/customer", method=RequestMethod.POST, produces="application/json; charset=UTF-8") (Stringcustomer(Customercustomer); }
value = "application"是注册中心的名称,不区分大小写:
Spring Cloud Feign在初始化过程中,@FeignClient注解会根据该注解的name属性或value属性指定的服务名,自动创建一个同名的Ribbon客户端。
Feign在默认情况下使用的是JDK原生URLConnection发送HTTP请求,没有连接池,但是对每个地址会保持一个长连接,即利用HTTP的persistence connection。
3.创建启动类
packagecom.xing.study.cloud.feign; importfeign.Logger; importorg.springframework.boot.SpringApplication; importorg.springframework.boot.autoconfigure.SpringBootApplication; importorg.springframework.cloud.client.discovery.EnableDiscoveryClient; importorg.springframework.cloud.netflix.eureka.EnableEurekaClient; importorg.springframework.cloud.openfeign.EnableFeignClients; importorg.springframework.context.annotation.Bean; /*** @author rt*/publicclassFeignApplication { publicstaticvoidmain(String[] args) { SpringApplication.run(FeignApplication.class, args); } }
这里主要是使用@EnableFeignClients注解来开启Feign组件。
4.配置文件和Eureka Client的都一样,端口换一下
spring.application.name=feignserver.port=8888eureka.instance.instance-id=feigneureka.client.service-url.defaultZone=http://172.23.13.15:8881/eureka/eureka.client.register-with-eureka=trueeureka.client.fetch-registry=true5.在Feign项目中使用Feign组件调用packagecom.xing.study.cloud.feign; importcom.xing.study.cloud.entity.Customer; importorg.springframework.web.bind.annotation.RequestMapping; importorg.springframework.web.bind.annotation.RestController; importjavax.annotation.Resource; /*** @author rt*/publicclassFeignController { OneApplicationFeignClientoneApplicationFeignClient; "/feign") (publicStringfeign() { return"feign调用成功->"+oneApplicationFeignClient.app(); } "/feign2") (publicStringfeign2() { return"feign调用成功->"+oneApplicationFeignClient.admin("中午吃馒头"); } "/feign3") (publicStringfeign3() { return"feign调用成功->"+oneApplicationFeignClient.customer(newCustomer("张三","男")); } }
6.测试
分别启动Eureka Server、OneApplication(也就是三个接口)、Feign项目测试结果,保证成功在注册中心注册了。
访问Feign发布的服务:
完美!
总结:
引入spring-cloud-starter-feign依赖
启动类@EnableFeignCleints注解开启FeignCleint。
创建与服务提供端对应的接口,并加@FeignCleint注解(初始化时扫描所有的@FeignCleint注解的类,并将这些信息注入到Spring容器中。
当接口的方法被调用,通过jdk的代理URLConnection来生成具体的RequesTemplate
RequesTemplate去生成Request
Request交给Client去处理,其中Client可以是HttpUrlConnection、HttpClient也可以是Okhttp
最后Client被封装到LoadBalanceClient类,这个类结合类Ribbon做到了负载均衡
最终实现了服务之间的相互调用,并且做到了客户端均衡负载(依赖Ribbon)。
总是懒得学源码!稍微看一会就烦躁,缺少兴趣的引导!浮躁滴很呐。
END