资料来源: <<重新定义Spring Cloud>>以及博客和官网
源码地址:https://gitee.com/08081/hello-springcloud
什么是feign ?
fegin是一种声明式 模板化的HTTP客户端(仅在consumer中使用)
1. 什么是声明式呢?
- 声明式调用就像调用本地方法一样调用远程方法,无感知远程http请求
- Spring Cloud的声明式调用,可以做到使用HTTP请求远程服务时就像调用本地方法一样的体验,开发者完全感知不到这是远程调用,更加不知道这是一个http请求
- 像dubbo一样,consumer直接调用接口方法调用provider,而不需要通过常规的httpclient构造在解析返回数据
- 解决了.开发者调用远程和调用本地一样,无需关心远程交互的细节,更无需关注分布式环境
2. 工作原理
- 在开发微服务应用时,我们会在主程序入口添加@EnableFeignClients注解开启对FeginClient扫描加载处理,
- 当程序启动时,会进行扫描,扫描所有@FeginClients的注解类,并将这些信息,注入到Spring IOC容器中. 当定义的fegin接口中的方法被调用时,通过JDK代理的方式,来生成具体的RequestTemplate,当生成代理时,Fegin会为每一个接口方法创建一个RequestTemplate对象,该对象封装了HTTP请求需要的全部信息,如请求参数,请求方法等信息都是在这个过程中确定的.
- 然后由RequestTemplate生成request,然后把request交给client去处理,这里说的client 可以是jdk中的urlConnection apache 的httpclient 最后client被封装到LoadBalanceClient类,这个类接口ribbon负载均衡发起服务之间的调用
入门案例
我们在父工程下创建ch4-fegin 这个父工程在他下面创建 3个模块
1. book-api: 主要作为一个接口给别的服务依赖,包含 实体对象,和api
2. book-service: 主要是作为book-api 的实现类模块
3.book-consumer: 调用book服务的类
下面是代码:
先看book-api的代码
实体类:
/** * Created by xiaodao * date: 2019/7/17 */ @Data @Builder @AllArgsConstructor @NoArgsConstructor public class Book { private int id; private String name; }
api:
package com.xiaodao.api; import com.xiaodao.entity.Book; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import java.util.List; /** * Created by xiaodao * date: 2019/7/17 */ @RequestMapping("/book") public interface BookApi { @GetMapping(value = "list") List<Book> findList(); }
pom:也是空的pom
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>ch4-fegin</artifactId> <groupId>com.xiaodao</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>ch4-book-api</artifactId> </project>
ch4-book-service的代码:
pom:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>ch4-fegin</artifactId> <groupId>com.xiaodao</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>ch4-book-service</artifactId> <dependencies> <dependency> <groupId>com.xiaodao</groupId> <artifactId>ch4-book-api</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies> </project
bootstrap.yml:
spring: application: name: book-service eureka: client: service-url: defaultZone: http://127.0.0.1:8888/eureka/ instance: prefer-ip-address: true server: port: 8000
bookserviceImpl:
package com.xiaodao.service; import com.xiaodao.api.BookApi; import com.xiaodao.entity.Book; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.ValueConstants; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; /** * Created by xiaodao * date: 2019/7/17 */ @RestController @RequestMapping("book") public class BookServiceImpl implements BookApi { @GetMapping(value = "list") @Override public List<Book> findList() { Book book =Book.builder().id(1).name("第一本书").build(); System.out.println(book); List<Book> list = new CopyOnWriteArrayList<>(); list.add(book); return list; } }