Spring Cloud中如何優雅的使用Feign調用接口

JAVA 項目中接口調用怎麼作 ?

  • Httpclient
  • Okhttp
  • Httpurlconnection
  • RestTemplate

上面是最多見的幾種用法,咱們今天要介紹的用法比上面的更簡單,方便,它就是 Feigngit

Feign是一個聲明式的REST客戶端,它的目的就是讓REST調用更加簡單。github

Feign提供了HTTP請求的模板,經過編寫簡單的接口和插入註解,就能夠定義好HTTP請求的參數、格式、地址等信息。spring

而Feign則會徹底代理HTTP請求,咱們只須要像調用方法同樣調用它就能夠完成服務請求及相關處理。api

SpringCloud對Feign進行了封裝,使其支持SpringMVC標準註解和HttpMessageConverters。app

Feign能夠與Eureka和Ribbon組合使用以支持負載均衡。負載均衡


SpringCloud中使用Feign

當咱們搭建好註冊中心Eureka以後,就是須要將本身的服務註冊到Eureka中,而後別的服務能夠直接調用。ide

首先呢是服務提供方須要註冊到Eureka中,這邊咱們新建一個房產服務fangjia-fsh-house-serviceui

fangjia-fsh-house-service中提供跟房子相關的接口,好比最簡單的獲取房子的基本信息this

/**
 * 獲取房產信息
 * @param houseId 房產編號
 * @return 
 */
 @GetMapping("/{houseId}")
 public ResponseData hosueInfo(@PathVariable("houseId")Long houseId) {
     return ResponseData.ok(houseService.getHouseInfo(houseId));
 }

另外咱們起一個項目來消費房產服務的這個接口,房產置換服務fangjia-fsh-substitution-service編碼

/**
 * 獲取置換信息
 * @param sid
 * @return
 */
 @GetMapping("/{sid}")
 public ResponseData substitutionInfo(@PathVariable("sid") Long sid) {
     return ResponseData.ok(substitutionService.getSubstitutionInfo(sid));
 }

在substitutionService中須要消費房產服務的獲取房產信息接口,通常的作法咱們都會經過Httpclient或者最底層的Httpurlconnection來直接調用接口,固然這些都須要本身集成或者封裝,在spring裏面已經有了一個很好的封裝,那就是RestTemplate來調用接口。

關於RestTemplate的使用能夠查看個人這篇文章:http://cxytiandi.com/blog/detail/6157

能夠直接注入對象,而後調用接口,這種方式惟一的弊端就是你須要知道服務提供者的地址,根據指定的地址來進行調用

@Autowired
private RestTemplate restTemplate;

@Override
public SubstitutionDto getSubstitutionInfo(Long sid) {
    House house = this.restTemplate.getForObject("http://localhost:8000/hosue/" + id, House.class);
  // .......
}

另外一種就是咱們今天的主角,簡單的調用方式就是使用一個聲明式的REST客戶端Feign來進行接口調用

用了Feign以後調用接口只須要定義相同的接口便可實現調用

使用Feign確定要引入jar的依賴

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-feign</artifactId>
</dependency>

在啓動類上加@EnableFeignClients註解,若是你的Feign接口定義跟你的啓動類不在一個包名下,還須要制定掃描的包名@EnableFeignClients(basePackages = "com.fangjia.api.client")

這邊建議你們將接口的消費定義,單獨抽一個項目出來,後面打成公共的jar,這樣不管是哪一個項目須要調用接口,引入公共的接口SDK jar便可,不用從新定義一遍了。

**
 * 房生活房產服務API調用客戶端
 *
 * @author yinjihuan
 * @create 2017-10-27 13:55
 **/
@FeignClient(value = "fangjia-fsh-house-service", path = "/house", configuration = FeignConfiguration.class, fallback = HouseRemoteClientHystrix.class)
public interface HouseRemoteClient {
    
    /**
     * 獲取企業下某用戶的有效房產信息
     * @param eid    企業編號
     * @param uid    用戶編號
     * @return
     */
    @GetMapping("/list/{eid}/{uid}")
    public HouseListDto hosueList(@PathVariable("eid")Long eid, @PathVariable("uid")String uid);    
    
    /**
     * 獲取房產詳細信息
     * @param houseId 房產編號
     * @return
     */
    @GetMapping("/{houseId}")
    public HouseInfoDto hosueInfo(@PathVariable("houseId")Long houseId);
    
}

@FeignClient裏的value表示你要消費哪一個服務的接口,path就是統一的前綴,也就是咱們HouseController中類上面的@RequestMapping("/house")的地址

@FeignClient裏的configuration可讓你自定義配置信息來覆蓋Feign的默認配置,
好比配置日誌輸出

日誌的輸出還須要在配置文件中指定才能生效logging.level.com.fangjia.api.client.fsh.house.HouseRemoteClient=DEBUG

@Configuration
public class FeignConfiguration {
    @Bean  
    Logger.Level feignLoggerLevel() {  
        return Logger.Level.FULL;  
    }  
}

@FeignClient裏的fallback可讓你的接口在熔斷處理時,返回默認的值給調用方,這個通常有2種方式:

  • 實現Feign的接口,實現全部的默認方法
/**
 * 房產服務調用熔斷默認返回處理
 *
 * @author yinjihuan
 * @create 2017-10-29 14:30
 **/
@Component
public class HouseRemoteClientHystrix implements HouseRemoteClient {

    @Override
    public HouseListDto hosueList(Long eid, String uid) {
        return new HouseListDto();
    }

    @Override
    public HouseInfoDto hosueInfo(Long houseId) {
        return new HouseInfoDto();
    }
}

另外一種就是@FeignClient裏的fallbackFactory,效果是同樣的

使用的話更簡單了,和普通的Service的類同樣使用,注入進來,而後直接調用方法就至關於調用遠程接口了

@Autowired
private HouseRemoteClient houseRemoteClient;

HouseInfoDto houseInfoDto = houseRemoteClient.hosueInfo(1L);

普通Java項目中如何使用Feign

經過上面的講解,在SpringCloud中使用Feign顯得那麼的天然,由於集成這件事SpringCloud已經幫咱們作好了,這是廣大開發人員的福音。

那若是大家沒有使用SpringCloud來進行開發,我能用Feign來調用接口馬,答案是:固然

首先你須要看一遍文檔,若是還不會用你來找我:https://github.com/OpenFeign/feign

咱們看官方的提個Demo:

定義了一個GitHub的接口調用類,上面配置了請求方式以及參數,是經過Feign自帶的註解方式配置的

而後經過Feign.builder()構建一個客戶端,同時能夠設置編碼,解碼須要用到的類,以及訪問的目標地址等等信息,固然也包括日誌的設置,輸出等等。。

interface GitHub {
  @RequestLine("GET /repos/{owner}/{repo}/contributors")
  List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repo);
}

static class Contributor {
  String login;
  int contributions;
}

public static void main(String... args) {
  GitHub github = Feign.builder()
                       .decoder(new GsonDecoder())
                       .target(GitHub.class, "https://api.github.com");

  // Fetch and print a list of the contributors to this library.
  List<Contributor> contributors = github.contributors("OpenFeign", "feign");
  for (Contributor contributor : contributors) {
    System.out.println(contributor.login + " (" + contributor.contributions + ")");
  }
}

具體代碼能夠參考個人github:

https://github.com/yinjihuan/spring-cloud

相關文章
相關標籤/搜索