springcloud(第八篇)springcloud feign

来源:互联网 发布:突破阶级的途径 知乎 编辑:程序博客网 时间:2024/05/29 16:03

# spring cloud feign

introduction

netflix feign是一个类似retrofit进行http调用框架,Feign makes writing java http clients easier 使得编写http client代码更加简单

netflix feign

直接给出一段简单的案例

package com.lkl.netflix.feign;import feign.*;import feign.codec.ErrorDecoder;import feign.codec.Decoder;import feign.gson.GsonDecoder;import java.io.IOException;import java.util.List;/** * Created by liaokailin on 16/5/9. */public class GitHubExample {    interface GitHub {  // 1        @RequestLine("GET /repos/{owner}/{repo}/contributors")        List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repo);    }    public static void main(String... args) {        Decoder decoder = new GsonDecoder();  // 2        GitHub github = Feign.builder()                .decoder(decoder) // 3                .errorDecoder(new GitHubErrorDecoder(decoder))  // 4                .logger(new Logger.ErrorLogger())  // 5                .logLevel(Logger.Level.BASIC)  // 5                .target(GitHub.class, "https://api.github.com");  // 6        System.out.println("Let's fetch and print a list of the contributors to this library.");        List<Contributor> contributors = github.contributors("netflix", "feign");  // 7        for (Contributor contributor : contributors) {            System.out.println(contributor.login + " (" + contributor.contributions + ")");        }        System.out.println("Now, let's cause an error.");        try {            github.contributors("netflix", "some-unknown-project");  // 8        } catch (GitHubClientError e) {            System.out.println(e.getMessage());        }    }    static class Contributor {        String login;        int contributions;    }    static class GitHubClientError extends RuntimeException {  // 4        private String message; // parsed from json        @Override        public String getMessage() {            return message;        }    }    static class GitHubErrorDecoder implements ErrorDecoder {   // 4        final Decoder decoder;        final ErrorDecoder defaultDecoder = new ErrorDecoder.Default();        GitHubErrorDecoder(Decoder decoder) {            this.decoder = decoder;        }        @Override        public Exception decode(String methodKey, Response response) {            try {                return (Exception) decoder.decode(response, GitHubClientError.class);            } catch (IOException fallbackToDefault) {                return defaultDecoder.decode(methodKey, response);            }        }    }}

1.首先定义接口GitHub,使用注解RequestLine 表明contributors()方法为一个get请求,请求相对为/repos/{owner}/{repo}/contributors
2.Decoder decoder = new GsonDecoder(); 创建一个GsonDecoder解码器,表明通过Gson解析返回数据
3.decoder()方法设置解码器
4.errorDecoder()指定发生异常时的解码器,需要实现ErrorDecoder接口,覆写decode方法,通过指定的Decoder解析错误信息,这里还是使用GsonDecoder
5.logger 相关的表示配置日志系你系
6.target() 方法指定访问url以及返回的类型
7.通过创建的github对象调用contributors获取结果
8.模拟异常情况

note: feign使用起来很简单,其原理和retrofit及其类似,通过接口定义访问访问,用jdk的动态代理创建接口的实现类,在类中解析方法上的注解信息用以识别用户配置的http请求信息,然后执行请求;
feign可以通过ReflectiveFeign下的newInstance()方法看到

return (T) Proxy        .newProxyInstance(target.type().getClassLoader(), new Class<?>[]{target.type()}, handler);

spring cloud feign

spring cloud feign通过注解的封装使用起来更加简单

package com.lkl.springcloud.feign;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.EnableAutoConfiguration;import org.springframework.cloud.netflix.feign.EnableFeignClients;import org.springframework.cloud.netflix.feign.FeignClient;import org.springframework.context.annotation.Configuration;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RestController;import java.util.List;/** * Created by liaokailin on 16/5/11. */@Configuration@EnableAutoConfiguration@EnableFeignClients@RestControllerpublic class Application {    @Autowired    GitHub gitHub;    public static void main(String[] args) {        SpringApplication.run(Application.class, args);    }    @FeignClient(url = "https://api.github.com")    interface GitHub {        @RequestMapping(value = "/repos/{owner}/{repo}/contributors", method = RequestMethod.GET)      ResponseEntity<List<Contributor>> contributors(@PathVariable("owner") String owner, @PathVariable("repo") String repo);    }    @RequestMapping("/")    public void test(){        ResponseEntity< List<Contributor>>  responseEntity  =   gitHub.contributors("netflix", "feign");        List<Contributor> contributors = responseEntity.getBody();         for (Contributor contributor : contributors) {         System.out.println(contributor.login + " (" + contributor.contributions + ")");         }    }    static class Contributor {        String login;        int contributions;    }}

注解EnableFeignClients表明需要扫描使用FeignClient注解的接口,在代码中定义了@FeignClient(url = "https://api.github.com") 表明该接口为一个feign接口
通过url指定访问路径RequestMapping表明相对路径

在代码中注入beanGitHub,直接调用其中申明的方法即可。

重点说明下FeignClient注解

该注解表示申明创建一个rest client bean,可以直接通过Autowired注入使用,如果ribbon在工程中启用,则会使用load balance进行后端请求调用,可以为FeignClient指定value表明需要访问的serviceId

feign + ribbon + eureka

在springcloud(第七篇)springcloud ribbon with eureka中讲解了ribbon+eureka,其中使用RestTemplate进行调用,也可以通过
feign调用

package com.lkl.springcloud.feign;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.cloud.netflix.feign.EnableFeignClients;import org.springframework.cloud.netflix.feign.FeignClient;import org.springframework.cloud.netflix.ribbon.RibbonClient;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import static org.springframework.web.bind.annotation.RequestMethod.GET;/** * Created by liaokailin on 16/5/9. */@SpringBootApplication@EnableDiscoveryClient@RestController@RibbonClient("hello")@EnableFeignClientspublic class Application {    @Autowired    HelloClient client;    @RequestMapping("/")    public String hello() {        return client.hello();    }    public static void main(String[] args) {        SpringApplication.run(Application.class, args);    }    @FeignClient("simple")    interface HelloClient {        @RequestMapping(value = "/", method = GET)        String hello();    }}

使用@FeignClient("simple")指定要访问的service id 由于hello()对应的mapping为@RequestMapping(value = "/", method = GET) 那么该方法实际调用url为
http://simple/,因此在执行

@RequestMapping("/")    public String hello() {        return client.hello();    }

调用的为SimpleApplication.java

@RequestMapping("/")    public String hello() {        return "Hello";    }

ok ~ it’s work ! more about is here
转载请注明
http://blog.csdn.net/liaokailin/article/details/51470051

欢迎关注,您的肯定是对我最大的支持

这里写图片描述

1 0
原创粉丝点击