SpringCloud整合Feign
1、準備工作
- 新建Maven項目:atm_spring_feign_server(8761端口)
新建Maven項目:atm_spring_feign_provider
- 啓動8080與8081端口
- 提供“/person/{personId}”與“/hello”服務
新建Maven項目:atm_spring_feign_invoker(9000端口)
2、服務調用者
2.1、引入依賴
- 爲服務提供者(atm_spring_feign_invoker)引入依賴
<!-- SpringCloud 整合 Feign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
2.2、啓動類打開Feign
package com.atm.cloud;
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//調用者啓動時,打開Feign開關
public class MySpringFeignInvoker {
public static void main(String[] args) {
SpringApplication.run(MySpringFeignInvoker.class, args);
}
}
2.3、編寫接口
package com.atm.cloud.interf;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* 客戶端服務接口
*
* 與單獨使用Feign不同:
* 1.接口需要使用@FeignClient註解修飾
* 2.聲明需要調用的服務名稱
*/
@FeignClient("atm-spring-feign-provider")
public interface PersonClient {
/**
* 之前得知:
* 通過編寫"翻譯器"(Contract),可以讓Feign知道第三方註解的含義
* 同樣,SpringCloud也提供了翻譯器,會將註解告訴Feign
* 因此,接口可以直接使用該註解
* 默認支持註解:@RequestMapping、@RequestParam、@RequestHeader、@PathVariable
* 【注意】使用了SpringCloud的翻譯器後,將不能再使用Feign的默認註解
*/
@GetMapping("/hello")
//@RequestMapping(method=RequestMethod.GET,value="/hello")
String sayHello();
@RequestMapping(method=RequestMethod.GET,value="/hello/{name}")
String hello(@PathVariable("name") String name);
}
2.4、控制器添加調用方法
package com.atm.cloud.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.atm.cloud.interf.PersonClient;
@RestController
@Configuration
public class MyInvokerController {
//在控制器中調用接口方法 ---start
@Autowired
private PersonClient personClient;
@RequestMapping(value="/invokeHello",method=RequestMethod.GET)
public String invokeHello(){
return personClient.sayHello();
}
//在控制器中調用接口方法 ---end
}
2.5、運行測試
- 啓動atm_spring_feign_server(8761端口)
- 啓動atm_spring_feign_provider(8080端口、8081端口)
- 啓動atm_spring_feign_invoker(9000端口)
- 瀏覽器訪問http://localhost:9000/invokerHello
- 可以發現:服務提供者的“/hello”被調用
3、Feign負載均衡
3.1、編寫接口
package com.atm.cloud;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* 客戶端服務接口
*
* 與單獨使用Feign不同:
* 1.接口需要使用@FeignClient註解修飾
* 2.聲明需要調用的服務名稱
*/
@FeignClient("atm-spring-feign-provider")
public interface PersonClient {
@RequestMapping(method = RequestMethod.GET, value = "/person/{personId}")
Person getPerson(@PathVariable("personId") Integer personId);
}
3.2、控制器添加調用方法
package com.atm.cloud;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.atm.cloud.PersonClient;
@RestController
@Configuration
public class MyInvokerController {
@RequestMapping(value = "/router", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String router() {
// 調用服務提供者的接口
Person p = personClient.getPerson(2);
return p.getName();
}
}
3.3、運行測試
- 瀏覽器訪問http://localhost:9000/router
- 可以發現,調用了提供者接口,輪詢訪問8080端口與8081端口
3.4、默認配置
- SpringCloud爲Feign的使用提供了各種默認屬性
- 默認情況下,Spring將會爲Feign的屬性提供bean
- 解碼器(Decoder):bean 名稱爲 feignDecoder,ResponseEntityDecoder 類
- 編碼器(Encoder):bean 名稱爲 feignEecoder,SpringEncoder 類
- 日誌(Logger): bean 名稱爲 feignLogger,Slf4jLogger 類
- 註解翻譯器(Contract): bean 名稱爲 feignContract,SpringMvcContract 類
package com.atm.cloud;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyUrl {
String url();
String method();
}
package com.atm.cloud;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import org.springframework.cloud.netflix.feign.support.SpringMvcContract;
import feign.Contract.BaseContract;
import feign.MethodMetadata;
//自定義翻譯器實現支持兩種註解
public class MyContract extends SpringMvcContract {
@Override
protected void processAnnotationOnMethod(MethodMetadata data,
Annotation annotation, Method method) {
super.processAnnotationOnMethod(data, annotation, method);
// 在父類的基礎上實現
// 實現自定義的翻譯邏輯
}
}
package com.atm.cloud;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import feign.Contract;
@Configuration
public class MyConfig {
@Bean
public Contract feignContract() {
return new MyContract();
}
}
@MyUrl(url="/hello",method="GET")
String hello();
- Feign 實 例 的 創 建 者 ( Feign.Builder ) : bean 名 稱 爲 feignBuilder ,HystrixFeign.Builder 類
- Feign 客戶端(Client):bean 名稱爲 feignClient,LoadBalancerFeignClient 類
3.5、可選配置
- Logger.level:接口日誌的記錄級別,相當於調用了Feign.Builder的level方法
- Retryer:重試處理器,相當於調用了Feign.Builder.的retryer方法
- ErrorDecoder:異常解碼器,相當於調用了Feign.Builder.的ErrorDecoder方法
- Request.Options:設置請求的配置項
- Collection”<”RequestInterceptor”>”:請求攔截器
3.6、壓縮配置
- feign.compression.request.enabled:設置爲true開啓請求壓縮
- feign.compression.response.enabled:設置爲true開啓響應壓縮
- feign.compression.request.mine-types:數據類型列表,默認爲text/xml,application/xml,application/json
- feign.compression.request.min-request-size:設置請求內容的最小閥值,默認2048