1.声明式服务调用的作用是什么,它解决了什么问题
1.什么是Feign?
Feign是一种声明式、模块化的HTT客户端(仅在consumer中使用)。
2.什么是声明式服务,有什么作,解决了什么问题。
1)声明式调用就像调用调用本地方法一样调用远程方法。
2)Spring Cloud的声明式调用,可以做到使用 HTTP请求远程服务时就像调用本地方法一样的体验,开发者完全感知不到这是远程方法,更不知这是一个Http请求。
3)他解决了让开发者调用远程接口就跟调用本地方法一样,无需关注与远程交互的细节,更无需关注分布式环境开发。
2.声明式服务的简单例子
1.首先我们需要一个api和proudct,目录结构如下:
api中主要就是写接口,然后product中主要就是写实现类。然后,我们还需要在proudct的pom文件中添加api的依赖:
<dependency>
<groupId>${project.parent.groupId}</groupId>
<artifactId>e-book-product-api</artifactId>
<version>${project.parent.version}</version>
</dependency>
2.api中Product的代码:
public class Product {
private int id;
private String name;
public Product() {
super();
// TODO Auto-generated constructor stub
}
public Product(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
这个就是创建一个类。
api中ProductFacede代码:
@RequestMapping("product")
public interface ProductFacade {
//无参
@RequestMapping(value="list",method=RequestMethod.GET)
public List<Product> listProduct();
//一个参数
@RequestMapping(value="get",method=RequestMethod.GET)
public Product getProduct(@RequestParam("id") Integer id);
//------------------------多参数----------------------
@RequestMapping(value="get1",method=RequestMethod.GET,consumes=MediaType.APPLICATION_JSON_VALUE)
public Product getProduct1(Product obj);
@RequestMapping(value="get2",method=RequestMethod.GET)
public Product getProduct2(@RequestParam("id") Integer id,@RequestParam("name") String name);
//------------------------POST-------------------------
@RequestMapping(value="add",method=RequestMethod.POST,consumes=MediaType.APPLICATION_JSON_VALUE)
public Product addProduct(@RequestBody Product obj);
}
这是api中的接口。
3.product中ProductFacedeImpl代码:
@RestController
public class ProductFacadeImpl implements ProductFacade{
@RequestMapping(value="list",method=RequestMethod.GET)
public List<Product> listProduct(){
System.out.println("########################");
try {
Thread.sleep(6*1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
List<Product> list= new ArrayList<Product>();
list.add(new Product(1,"tes矢付撒发付付撒奥过过过过过过过过"));
list.add(new Product(2,"test2无付撒发付付撒奥过过过过过过过过"));
list.add(new Product(3,"tes付撒发付付撒奥过过过过过过过过"));
return list;
}
@Override
public Product getProduct(Integer id) {
return new Product(id,"test4");
}
@Override
public Product getProduct1(@RequestBody Product obj) {
return obj;
}
@Override
public Product getProduct2(Integer id, String name) {
return new Product(id,name);
}
@Override
public Product addProduct(@RequestBody Product obj) {
return obj;
}
}
到这里基本上api和product的代码就大功告成了。然后就是需要的consumer使用这里面的方法就OK了。
4.consumer声明式调用方法。
首先我们需要在consumer的pom中加入api和feign的依赖:
<dependency>
<groupId>${project.parent.groupId}</groupId>
<artifactId>e-book-product-api</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
consumer中的目录结构:
需要写的其实就ProductController和ProductService,而且这两个代码量非常的少就能使用方法。
ProductController中的代码:
@RestController
public class ProductController {
@Autowired
private ProductService productService;
@RequestMapping(value="list",method=RequestMethod.GET)
public List<Product> listProduct(){
List<Product> list= this.productService.listProduct();
return list;
}
}
ProductService中的代码:
@FeignClient(name="e-book-product")
public interface ProductService extends ProductFacade{
}
这个就是一个接口然后继承了api中ProductFacade接口。然后consumer中的controller就可以调用api中的方法了。FeignClient中是product项目的名称。
启动eureka,product,consumer,测试结果:
这里只是一个简单例子,关于feign还有处理复杂参数,Gzip,连接池,日志记录,负载均衡相关的知识,在后面我也会记录下来,给自己和他人做个记录。