SpringCloud入门实战(5)-Feign使用

Feign是一种声明式、模板化的HTTP客户端。在Spring Cloud中使用Feign,可以做到调用远程服务,就像调用本地方法一样的,开发者完全感知不到这是在调用远程方法,更感知不到在访问HTTP请求。本文主要介绍Feign的基本使用,文中使用到的软件版本:Spring Boot 2.2.5.RELEASE、Spring Cloud Hoxton.SR3、Java 1.8.0_191。

1、特点

a、Feign可帮助我们更加便捷,优雅的调用HTTP API。
b、在SpringCloud中,使用Feign非常简单——创建一个接口,并在接口上添加一些注解,代码就完成了。
c、Feign支持多种注解,例如Feign自带的注解或者JAX-RS注解等。
d、SpringCloud对Feign进行了增强,使Feign支持了SpringMVC注解,并整合了Ribbon,从而让Feign的使用更加方便。

2、原理

3、常用参数设置

feign.hystrix.enabled=false feign的调用过程中是否启用hystrix,默认false
feign.httpclient.enabled=ture 是否使用httpclient来调用接口,默认true;要使用httpclient还需要引入feign-httpclient依赖
feign.okhttp.enabled=false 是否使用okhttp来调用接口,默认false;要使用okhttp需把改属性设为true,还需要引入feign-httpclient依赖

4、使用

4.1、客户端引入依赖

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

4.2、客户端启动类增加@EnableFeignClients

package com.abc.scdemo.client;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class ClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(ClientApplication.class, args);
    }
}

4.3、服务端 Controller

package com.abc.scdemo.server.controller;

import com.abc.scdemo.server.entity.CallResult;
import com.abc.scdemo.server.entity.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
public class UserController {
    private Logger logger = LoggerFactory.getLogger(UserController.class);
    
    @RequestMapping("/addUser")
    public CallResult<User> addUser(@RequestBody User user) {
        logger.info(user.toString());
        //TODO: insert to db
        user.setId(1000L);
        user.setName("server-" + user.getName());
        CallResult<User> result = new CallResult<>();
        result.setResult(user);
        return result;
    }
    
    @RequestMapping("/getUser")
    public CallResult<User> getUser(long id) {
        logger.info(id + "");

//        try {
//            Thread.sleep(1000 * 10);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        //TODO: select from db
        User user = new User();
        user.setId(id);
        user.setName("server-马云");
        user.setAddress("杭州");
        CallResult<User> result = new CallResult<User>();
        result.setResult(user);
        return result;
    }

    @RequestMapping("/getUser2")
    public CallResult<User> getUser2(long id) {
        return null;
    }
}

4.4、客户端定义Feign接口

package com.abc.scdemo.client.feign;

import com.abc.scdemo.client.entity.CallResult;
import com.abc.scdemo.client.entity.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

//scdemo-server为服务名称
@FeignClient(name = "scdemo-server")
public interface IUserFeign {
    @PostMapping("/user/addUser")
    CallResult<User> addUser(@RequestBody User user);

    @PostMapping("/user/getUser")
    CallResult<User> getUser(@RequestParam("id") long id);
}

4.5、客户端调用

@RequestMapping("/getUser")
public CallResult<User> getUser(long id) {
    logger.info(id + "");

    CallResult<User> result = null;
    try {
        result = userFeign.getUser(id);
    } catch (Exception e) {
        result = new CallResult<User>(-1, "发生异常");
        e.printStackTrace();
    }
    return result;
}

4.5、与Hystrix结合使用

4.5.1、配置启用Hystrix

feign:
  hystrix:
    enabled: true

4.5.2、定义降级实现类

package com.abc.scdemo.client.feign.fallback;

import com.abc.scdemo.client.entity.CallResult;
import com.abc.scdemo.client.entity.User;
import com.abc.scdemo.client.feign.IUserFeign;
import org.springframework.stereotype.Component;

@Component
public class UserFallBack implements IUserFeign {
    @Override
    public CallResult<User> addUser(User user) {
        return new CallResult<>(1, "增加用户服务暂不可用!");
    }

    @Override
    public CallResult<User> getUser(long id) {
        return new CallResult<>(1, "获取用户服务暂不可用!");
    }
}

4.5.3、Feign接口中指定降级实现类

package com.abc.scdemo.client.feign;

import com.abc.scdemo.client.entity.CallResult;
import com.abc.scdemo.client.entity.User;
import com.abc.scdemo.client.feign.fallback.UserFallBack;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

//scdemo-server为服务名称
@FeignClient(name = "scdemo-server", fallback = UserFallBack.class)
public interface IUserFeign {
    @PostMapping("/user/addUser")
    CallResult<User> addUser(@RequestBody User user);

    @PostMapping("/user/getUser")
    CallResult<User> getUser(@RequestParam("id") long id);
}

当scdemo-server服务不存在或调用超时,都会返回降级实现类中的结果。

posted @ 2020-08-30 16:20  且行且码  阅读(433)  评论(0编辑  收藏  举报