Spring Cloud : OpenFeign(远程调用)

RestTemplate虽然比直接用HTTPClient简单的多,但是还是存在着许多的问题,比如url拼接麻烦,容易出错,并且可读性很差

    public OrderDetail selectOrderById(Integer orderId){
        OrderDetail orderDetail = orderMapper.selectOrderById(orderId);
        String url="http://product-service/product/"+orderDetail.getProductId();
        ProductDetail productDetail = restTemplate.getForObject(url, ProductDetail.class);
        orderDetail.setProductDetail(productDetail);
        return orderDetail;
    }

OpenFeign

微服务之间的通信,通常有RPC和HTTP,在SpringCloud中默认使用HTTP来进行微服务的通信,最常用的两种形式:RestTemplate和OpenFeign

OpenFeign是⼀个声明式的WebService客⼾端.它让微服务之间的调⽤变得更简单,类似controller 调⽤service, 只需要创建⼀个接⼝,然后添加注解即可使⽤OpenFeign

OpenFeign的使用

引入依赖

       <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

添加注解@EnableFeignClients

        用来开启OpenFeign的功能 

@EnableFeignClients
@SpringBootApplication
@MapperScan("org.example1.mapper")
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class,args);
    }
}

写一个关于OpenFeign的客⼾端

        用SpringMvc的注解进行调用

@FeignClient(value = "product-service", path = "/product")
public interface ProductApi {

    @RequestMapping("/{productId}")
    ProductDetail selectProductById(@RequestParam("productId") Integer productId);


    @RequestMapping("/p1")
    String p1(@RequestParam("id") Integer id);

    @RequestMapping("/p2")
    String p2(@RequestParam("id") Integer id,@RequestParam("name") String name);

    @RequestMapping("/p3")
    String p3(@SpringQueryMap ProductDetail productDetail);

    @RequestMapping("/p4")
    String p4(@RequestBody ProductDetail productDetail);
}

 

 远程调用

@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private ProductApi productApi;

    public OrderDetail selectOrderById(Integer orderId){
        OrderDetail orderDetail = orderMapper.selectOrderById(orderId);
ProductDetail.class);
        ProductDetail productDetail = productApi.selectProductById(orderDetail.getProductId());
        orderDetail.setProductDetail(productDetail);
        return orderDetail;
    }
}

 

OpenFeign关于参数的传递

包括一个参数,两个参数,传递对象,传递Json

首先我们在product-service中提供几个接口方法

@RestController
@RequestMapping("/product")
public class ProductController {

    @Autowired
    private ProductService productService;


    @RequestMapping("p1")
    private String p1(Integer id){
        return "参数传递:"+id;
    }

    @RequestMapping("p2")
    private String p2(Integer id,String name){
        return "参数传递,id:"+id+"name"+name;
    }

    @RequestMapping("p3")
    private String p3(ProductDetail productDetail){
        return "传递对象"+productDetail;
    }

    @RequestMapping("p4")
    private String p4(@RequestBody ProductDetail productDetail){
        return "接受Json对象"+productDetail;
    }

}

在Feign客户端

@FeignClient(value = "product-service", path = "/product")
public interface ProductApi {

    @RequestMapping("/p1")
    String p1(@RequestParam("id") Integer id);

    @RequestMapping("/p2")
    String p2(@RequestParam("id") Integer id,@RequestParam("name") String name);

    @RequestMapping("/p3")
    String p3(@SpringQueryMap ProductDetail productDetail);

    @RequestMapping("/p4")
    String p4(@RequestBody ProductDetail productDetail);
}

最后通过order-service服务调用

@RequestMapping("/feign")
@RestController
public class FeignController {
    @Autowired
    private ProductApi productApi;

    @RequestMapping("/o1")
    public String o1(Integer id){
        return productApi.p1(id);
    }
    @RequestMapping("/o2")
    public String o2(Integer id,String name){
        return productApi.p2(id,name);
    }
    @RequestMapping("/o3")
    public ProductDetail o3(){
        ProductDetail productDetail=new ProductDetail();
        productApi.p3(productDetail);
        productDetail.setId(1);
        productDetail.setProductName("zhangsan");
        return productDetail;
    }
    @RequestMapping("/o4")
    public ProductDetail o4(){
        ProductDetail productDetail=new ProductDetail();
        productApi.p3(productDetail);
        productDetail.setId(1);
        productDetail.setProductName("zhangsan");
        return productDetail;
    }

}

 我们可以来测试一下

传递一个参数的

传递两个参数的

传递对象的

传递Json对象的

Feign 继承⽅式

Feign支持继承的方式,我们可以把一些常见的操作封装到接口中

创建一个新的服务product-api

将Feign客户端写在这个服务中,这样在调用的时候就不用再重写了

将Feign继承product-api

@FeignClient(value = "product-service", path = "/product")
public interface ProductApi extends org.example.ProductApi {

}

注:在product-api服务中记得写入依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

 在写好product-api服务后,将其install到本地

然后再重新测试一下

Feign 抽取⽅式

就是直接将Feign写成一个独立的模块,将product-service中的product-api接口删除

然后重新启动程序,发现报错了

我们需要再启动类中添加 

@EnableFeignClients(clients = {ProductApi.class})
@SpringBootApplication
@MapperScan("org.example1.mapper")
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class,args);
    }
}

标明需要加载的Feign客⼾端 

注:在部署服务的时候需要修改pom文件

 

希望对大家有所帮助!!!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值