openfeign介绍
在微服务设计里,服务之间的调用是很正常的,通常我们使用httpClient来实现对远程资源的调用,而这种方法需要知识服务的地址,业务接口地址等,而且需要等他开发完成后你才可以去调用它,这对于集成开发来说,不是什么好事 ,产生了A业务与B业务的强依赖性,那么我们如何进行解耦呢,答案就是openfeign框架,它与是springcloudy里的一部分。
springcloud的服务消费者指的就是服务间的调用,实现的方式有两种:一种就是上一章讲的restTemplate+ribbon,另一种就是本章要讲的feign,feign默认集成了ribbon,所以feign也默认实现了负载均衡。
服务发现/注册里的服务名
通过服务名来进行请求的发送要比配置域名发http更直观,并且你不需要知道它的域名和端口,这也是各个微服务之前直观调用的一种方式,而且A服务可以不依赖于B服务,只要知道接口签名即可。
graph TDB(服务b)-->C(eureka注册中心)D-->|在服务a中建立client服务名为服务b|E(openfeign服务端)A(服务a)-->|配置某个服务中心的服务名称|D(调用服务b的某个接口)D-->C
添加包引用
'org.springframework.cloud:spring-cloud-starter-openfeign'
添加配置bootstrap.yml
feign: client: config: default: connectTimeout: 2000 readTimeout: 10000
2 定义profile相关配置
//默认的一些文件路径的配置sourceSets { integTest { java.srcDir file('src/test/java') resources.srcDir file('src/test/resources') }}task integTest(type: Test) { testClassesDirs = sourceSets.test.output.classesDirs classpath = sourceSets.test.runtimeClasspath}
定义服务接口
定义伪方法,就是服务里的方法,你要知识方法参数和它的返回值,实现不用管,只在单元测试里MOCK就可以.
package test.lind.javaLindDay.feignClientDemo;import org.springframework.cloud.openfeign.FeignClient;import org.springframework.context.annotation.Profile;import org.springframework.web.bind.annotation.GetMapping;/** * 模拟其他服务. */@Profile("!integTest")@FeignClient(name = "serviceName",primary=false)public interface MockClient { @GetMapping(path = "/balanceSheet/{clientCode}") String balanceSheet(String clientCode);}
Profile的作用
profile就是环境变量,你在类上通过ActiveProfile去激活它,在使用它时,有过Profile注解来使用上,上面代码中MockClient对象不能在integTest环境下使用。
添加MOCK实现,它是自动注入的,所以声明@Bean注解
它是为了在单元测试环境下使用client,而又不希望与外部 网络资源通讯,所以需要mock一下本地资源去实现client.
package test.lind.javaLindDay;import static org.mockito.ArgumentMatchers.anyString;import static org.mockito.Mockito.mock;import static org.mockito.Mockito.when;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Profile;import test.lind.javaLindDay.feignClientDemo.MockClient;@Configuration@Profile("integTest")public class MockClientTest { @Bean @Primary public MockClient mockClient() { MockClient client = mock(MockClient.class); when(client.balanceSheet( anyString())) .thenReturn("OK"); return client; }}
添加单元测试,注意在单元测试上一定要指定它的环境变量
package test.lind.javaLindDay;import static org.junit.Assert.assertEquals;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.ActiveProfiles;import org.springframework.test.context.junit4.SpringRunner;import test.lind.javaLindDay.feignClientDemo.MockClient;@RunWith(SpringRunner.class)@SpringBootTest//指定profile环境@ActiveProfiles("integTest")public class JavaLindDayApplicationTests { @Autowired MockClient mockClient; @Test public void testMockClient() { assertEquals(mockClient.balanceSheet("OK"), "OK"); }}
运行测试后,MockClient将会被注入,它将使用Mock实现类,因为只有Mock实现类的Profile是指向integtest环境的。有了openfeign,以后开发服务对服务调用就可以解耦了!
feignClient发送multipart/form-data请求
- 需要先安装插件,默认是不能发送文件流的
<dependencies> ... <dependency> <groupId>io.github.openfeign.form</groupId> <artifactId>feign-form</artifactId> <version>3.3.0</version> </dependency> <dependency> <groupId>io.github.openfeign.form</groupId> <artifactId>feign-form-spring</artifactId> <version>3.3.0</version> </dependency> ...</dependencies>
- 添加bean
@FeignClient(name = "file-upload-service", configuration = FileUploadServiceClient.MultipartSupportConfig.class)public interface FileUploadServiceClient extends IFileUploadServiceClient { public class MultipartSupportConfig { @Autowired private ObjectFactory<HttpMessageConverters> messageConverters; @Bean public Encoder feignFormEncoder() { return new SpringFormEncoder(new SpringEncoder(messageConverters)); } }}
如果不需要Spring标准的编码,也可以这样实现
@FeignClient(name = "file-upload-service", configuration = FileUploadServiceClient.MultipartSupportConfig.class)public interface FileUploadServiceClient extends IFileUploadServiceClient { public class MultipartSupportConfig { @Bean public Encoder feignFormEncoder() { return new SpringFormEncoder(); } }}
- 添加注解
// File parameter @RequestLine("POST /send_photo") @Headers("Content-Type: multipart/form-data") void sendPhoto (@Param("is_public") Boolean isPublic, @Param("photo") File photo); // byte[] parameter @RequestLine("POST /send_photo") @Headers("Content-Type: multipart/form-data") void sendPhoto (@Param("is_public") Boolean isPublic, @Param("photo") byte[] photo); // FormData parameter @RequestLine("POST /send_photo") @Headers("Content-Type: multipart/form-data") void sendPhoto (@Param("is_public") Boolean isPublic, @Param("photo") FormData photo);
原文转载:http://www.shaoqun.com/a/504384.html
blibli:https://www.ikjzd.com/w/1676
网络星期一:https://www.ikjzd.com/w/80
openfeign介绍在微服务设计里,服务之间的调用是很正常的,通常我们使用httpClient来实现对远程资源的调用,而这种方法需要知识服务的地址,业务接口地址等,而且需要等他开发完成后你才可以去调用它,这对于集成开发来说,不是什么好事,产生了A业务与B业务的强依赖性,那么我们如何进行解耦呢,答案就是openfeign框架,它与是springcloudy里的一部分。 springcloud
prime day:prime day
e邮包:e邮包
深圳有哪些爬山的公园?:深圳有哪些爬山的公园?
关于亚马逊关键词的构建与拓展:关于亚马逊关键词的构建与拓展
番禺海傍水乡团购多少钱?海傍生态乐园团购价格?:番禺海傍水乡团购多少钱?海傍生态乐园团购价格?
没有评论:
发表评论