springboot~openfeign從此和httpClient說再見
在微(wei)服務(wu)(wu)設計里,服務(wu)(wu)之(zhi)間的(de)調用(yong)是(shi)很正常的(de),通常我(wo)們(men)使用(yong)httpClient來實現對(dui)(dui)遠程(cheng)資源的(de)調用(yong),而(er)這種方法需要知(zhi)識服務(wu)(wu)的(de)地(di)址,業務(wu)(wu)接口(kou)地(di)址等,而(er)且需要等他開發完成(cheng)后你才可(ke)以去調用(yong)它(ta),這對(dui)(dui)于(yu)集成(cheng)開發來說,不(bu)是(shi)什么(me)好事 ,產生了A業務(wu)(wu)與B業務(wu)(wu)的(de)強依賴(lai)性,那么(me)我(wo)們(men)如(ru)何(he)進行解(jie)耦(ou)呢,答案就(jiu)是(shi)openfeign框架,它(ta)與是(shi)springcloudy里的(de)一部分。
1 添加包引用
'org.springframework.cloud:spring-cloud-starter-openfeign',
注意如果(guo)你沒有引用springcloudy版本人有太(tai)多,需要先聲明(ming)它
dependencyManagement { imports { mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" } }
2 定義profile相關配置
//默認的一(yi)些文件路徑(jing)的配置 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 }
3 定義服務接口,定義偽方法,就是服務里的方法,你要知識方法參數和它的返回值,實現不用管,只在單元測試里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; /** * 模(mo)擬(ni)其他(ta)服(fu)務. */ @Profile("!integTest") @FeignClient(name = "serviceName") public interface MockClient { @GetMapping(path = "/balanceSheet/{clientCode}") String balanceSheet(String clientCode); }
4 Profile的作用
profile就是(shi)環境(jing)變量,你在類上通過ActiveProfile去激活它,在使(shi)(shi)用(yong)它時(shi),有過Profile注解(jie)來使(shi)(shi)用(yong)上,上面代碼(ma)中MockClient對象(xiang)不能在integTest環境(jing)下(xia)使(shi)(shi)用(yong)。
5 添加MOCK實現,它是自動注入的,所以聲明@Bean注解
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 public MockClient mockClient() { MockClient client = mock(MockClient.class); when(client.balanceSheet( anyString())) .thenReturn("OK"); return client; } }
6 添加單元測試,注意在單元測試上一定要指定它的環境變量
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將會被注(zhu)入,它(ta)將使用Mock實現(xian)類,因為只有Mock實現(xian)類的Profile是指(zhi)向integtest環境的。
有了(le)openfeign,以(yi)后開發服務對服務調(diao)用(yong)就可以(yi)解耦了(le)!