声明式服务调用Feign

什么是 Feign
Feign 是种声明式、模板化的 HTTP 客户端(仅在 consumer 中使用)。
 
什么是声明式,有什么作用,解决什么问题?
声明式调用就像调用本地方法一样调用远程方法;无感知远程 http 请求。
1,Spring Cloud 的声明式调用, 可以做到使用 HTTP 请求远程服务时能就像调用本地方法一样的体验,开发者完全感知不到这是远程方法,更感知不到这是个 HTTP 请求。
2,它像 Dubbo一样,consumer 直接调用接口方法调用 provider,而不需要通过常规的 Http Client 构造请求再解析返回数据。
3,它解决了让开发者调用远程接口就跟调用本地方法样,无需关注与远程的交互细节,更无需关注分布式环境开发。

声明式服务调用Feign

项目架构

声明式服务调用Feign

spring-boot-feign-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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.11.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.bjsxt</groupId>
<artifactId>spring-boot-feign-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-feign-service</name>
<description>spring-boot-feign-service</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR4</spring-cloud.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency> <dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies> <dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>

实体类

com.bjsxt.pojo.Product

package com.bjsxt.pojo;

import lombok.Data;

@Data
public class Product {
private int id;
private String name; public Product(int id, String name) {
this.id = id;
this.name = name;
} public Product() {
}
}

接口(Feign的核心之一)

com.bjsxt.service.ProduceService

package com.bjsxt.service;

import com.bjsxt.pojo.Product;
import org.springframework.web.bind.annotation.*; import java.util.List; @RequestMapping("/product")
public interface ProduceService { /**
* 查询所有产品
* @return
*/
@RequestMapping(value = "/findall",method = RequestMethod.GET)
public List<Product> findAll(); /**
* 根据商品id,查询商品
* @param id
* @return
*/
@RequestMapping(value = "/findbyid",method = RequestMethod.GET)
public Product getProductById(@RequestParam("id") Integer id); /**
* 新增商品 get方式
* @param id
* @param name
*/
@RequestMapping(value = "/add",method = RequestMethod.GET)
public Product addproduct(@RequestParam("id") Integer id,@RequestParam("name") String name); /***
* 新增商品 post方式
* @param product
* @return
*/
@RequestMapping(value = "/add",method = RequestMethod.POST)
public Product addPro(@RequestBody Product product);
}

生产者

pom文件(关联server)

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.11.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.bjsxt</groupId>
<artifactId>spring-boot-feign-prodvider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-feign-prodvider</name>
<description>spring-boot-feign-prodvider</description> <properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR4</spring-cloud.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <!--导入service-->
<dependency>
<groupId>com.bjsxt</groupId>
<artifactId>spring-boot-feign-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies> <dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>

配置文件

src/main/resources/application.properties

spring.application.name=yxfProductProvider
server.port=9001 #设置服务注册中心地址,指向另一个注册中心
eureka.client.service-url.defaultZone=http://admin:1234@192.168.41.242:5050/eureka/,http://admin:1234@192.168.41.242:5051/eureka/

控制层(Feign的核心之一)

com.bjsxt.controller.ProductController

package com.bjsxt.controller;

import com.bjsxt.pojo.Product;
import com.bjsxt.service.ProduceService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList;
import java.util.List; @RestController
public class ProductController implements ProduceService {
@Override
public List<Product> findAll() {
List<Product> list=new ArrayList<>();
list.add(new Product(1,"电视"));
list.add(new Product(2,"风扇"));
list.add(new Product(3,"冰箱"));
list.add(new Product(4,"电脑"));
return list;
} @Override
public Product getProductById(Integer id) {
return new Product(id,"SpringCloud");
} @Override
public Product addproduct(Integer id, String name) {
return new Product(id,name);
} @Override
public Product addPro(Product product) {
return product;
}
}

启动类

com.bjsxt.SpringBootFeignProdviderApplication

package com.bjsxt;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @SpringBootApplication
@EnableEurekaClient
public class SpringBootFeignProdviderApplication { public static void main(String[] args) {
SpringApplication.run(SpringBootFeignProdviderApplication.class, args);
} }

消费者

pom文件(同样关联server)

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.11.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.bjsxt</groupId>
<artifactId>spring-boot-feign-consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-feign-consumer</name>
<description>spring-boot-feign-consumer</description> <properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR4</spring-cloud.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--导入service-->
<dependency>
<groupId>com.bjsxt</groupId>
<artifactId>spring-boot-feign-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.4.RELEASE</version>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies> <dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>

配置文件

src/main/resources/application.properties

spring.application.name=yxfProductConsumer
server.port=9002 #设置服务注册中心地址,指向另一个注册中心
eureka.client.service-url.defaultZone=http://admin:1234@192.168.41.242:5050/eureka/,http://admin:1234@192.168.41.242:5051/eureka/

接口(继承服务的接口)

com.bjsxt.service.ProduceConsumerService

package com.bjsxt.service;

import com.bjsxt.service.ProduceService;
import org.springframework.cloud.openfeign.FeignClient; @FeignClient(name = "yxfProductProvider")
public interface ProduceConsumerService extends ProduceService {
}

控制层

com.bjsxt.controller.ProductConsumerController

package com.bjsxt.controller;

import com.bjsxt.service.ProduceConsumerService;
import com.bjsxt.pojo.Product;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import java.util.List; @RestController
public class ProductConsumerController { @Autowired
private ProduceConsumerService produceConsumerService; /**
* 查询所有
* @return
*/
@RequestMapping(value = "/pro",method = RequestMethod.GET)
public List<Product> getProduce(){
List<Product> all = produceConsumerService.findAll();
return all;
} /**
* 根据id,获取商品,传递单个参数
* @param id
* @return
*/
@RequestMapping(value = "/get",method = RequestMethod.GET)
public Product getProducebyid(@RequestParam("id") Integer id){
Product product = produceConsumerService.getProductById(id);
return product;
} /**
* 添加商品,传递多个参数 get方式
* @param id
* @param name
* @return
*/
@RequestMapping(value = "/add",method = RequestMethod.GET)
public Product addProduct(@RequestParam("id") Integer id,@RequestParam("name") String name){
Product product = produceConsumerService.addproduct(id,name);
return product;
} /**
* 添加商品,传递多个参数,内部是post
* @param product
* @return
*/
@RequestMapping(value = "/addpro",method = RequestMethod.GET)
public Product addPro(Product product){
Product pro = produceConsumerService.addPro(product);
return pro;
} }

启动类

com.bjsxt.SpringBootFeignConsumerApplication

package com.bjsxt;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients; @EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class SpringBootFeignConsumerApplication { public static void main(String[] args) {
SpringApplication.run(SpringBootFeignConsumerApplication.class, args);
} }
上一篇:SpringCloud开发学习总结(七)—— 声明式服务调用Feign(二)


下一篇:poj 2230详解