1.声明式服务调用的作用是什么,它解决了什么问题

1.什么是Feign?
Feign是一种声明式、模块化的HTT客户端(仅在consumer中使用)。
2.什么是声明式服务,有什么作,解决了什么问题。
1)声明式调用就像调用调用本地方法一样调用远程方法。
2)Spring Cloud的声明式调用,可以做到使用 HTTP请求远程服务时就像调用本地方法一样的体验,开发者完全感知不到这是远程方法,更不知这是一个Http请求。
3)他解决了让开发者调用远程接口就跟调用本地方法一样,无需关注与远程交互的细节,更无需关注分布式环境开发。

2.声明式服务的简单例子

1.首先我们需要一个api和proudct,目录结构如下:

feign 性能监控 feign produces_声明式服务例子


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中的目录结构:

feign 性能监控 feign produces_Feign_02


需要写的其实就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 性能监控 feign produces_feign 性能监控_03


这里只是一个简单例子,关于feign还有处理复杂参数,Gzip,连接池,日志记录,负载均衡相关的知识,在后面我也会记录下来,给自己和他人做个记录。