Feign声明式远程调用
# 前言
feign是一个声明式的HTTP客户端,他的目的就是让远程调用更加简单。给远程服务发的是HTTP请求。
# 远程调用步骤
# 引入open-feign依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
1
2
3
4
2
3
4
# 使用@FeignClient编写接口
会员服务(member)想要远程调用优惠券服务(conpon),只需要给会员服务里引入openfeign依赖,他就有了远程调用其他服务的能力。
在member模块下新建一个feign包,在feign包下新建专属的接口。
package com.elite.mall.member.feign;
import com.elite.mall.common.utils.CommonResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
// 声明调用什么微服务
@FeignClient("elitemall-coupon")
public interface CouponFeignService {
/**
* 测试
*/
@GetMapping("/coupon/coupons/member")
public CommonResult memberCouponList();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 注意
- 调用什么远程接口,需要去nacos注册中心查看对应的name
- 接口路径要写全,如下,不能只写member,要将路径写全。
controller.java
@RestController
@RequestMapping("coupon/coupons")
public class CouponController {
@Autowired
private CouponService couponService;
/**
* 测试
*/
@GetMapping("/member")
public CommonResult memberCouponList() {
CouponEntity couponEntity = new CouponEntity();
couponEntity.setCouponName("满100减去10");
return CommonResult.ok().put("couponList", Arrays.asList(couponEntity));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 开启远程调功能
在member模块启动类下,使用@EnableFeignClients
package com.elite.mall.member;
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(basePackages = "com.elite.mall.member.feign")
@EnableDiscoveryClient
@SpringBootApplication
public class ElitemallMemberApplication {
public static void main(String[] args) {
SpringApplication.run(ElitemallMemberApplication.class, args);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
basePackages 会扫描指定路径下,使用了@FeignClinte的接口。
# 验证
在member模块下的任意controller,新建一个接口
这里做演示代码,就写在controller中了,实际开发都是写实现类中
@GetMapping("/test")
public CommonResult test(){
MemberEntity memberEntity = new MemberEntity();
memberEntity.setNickname("测试名字");
CommonResult commonResult = couponFeignService.memberCouponList();
return CommonResult.ok().put("member", memberEntity).put("couponList", commonResult.get("couponList"));
}
1
2
3
4
5
6
7
2
3
4
5
6
7
重启member服务和coupon服务
访问:http://localhost:8000/member/members/test
返回:
{"msg":"success","code":200,"couponList":[{"id":null,"couponType":null,"couponImg":null,"couponName":"满100减去10","num":null,"amount":null,"perLimit":null,"minPoint":null,"startTime":null,"endTime":null,"useType":null,"note":null,"publishCount":null,"useCount":null,"receiveCount":null,"enableStartTime":null,"enableEndTime":null,"code":null,"memberLevel":null,"publish":null}],"member":{"id":null,"levelId":null,"username":null,"password":null,"nickname":"测试名字","mobile":null,"email":null,"header":null,"gender":null,"birth":null,"city":null,"job":null,"sign":null,"sourceType":null,"integration":null,"growth":null,"status":null,"createTime":null}}
1
2
2
搜素一个json在线格式化网站,把上面的json数据放进去
{
"msg": "success",
"code": 200,
"couponList": [{
"couponName": "满100减去10",
}],
"member": {
"nickname": "测试名字",
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
很明显,远程调用已经成功。
# 网关和远程调用
实际上,远程调用接口有2种方式
- 直接让后台指定服务处理
- 让所有请求过网关
很明显,上面用的是第一种方法。如果是第二种方法,实现方式也很简单。
# 实现方式
关键就在fegin接口,改成下面这样就行了。
@FeignClient("elitemall-gateway")
@GetMapping("/api/coupon/coupons/member")
给网关所在的机器发请求,这样子就可以了,
# 总结
远程调用微服务有两种方式:
- 直接让后台指定服务处理
接口:
@FeignClient("elitemall-coupon")
请求路径:
@GetMapping("/coupon/coupons/member")
- 让请求过网关处理
接口:
@FeignClient("elitemall-gateway")
请求路径:
@GetMapping("/api/coupon/coupons/member")
帮我改善此页面 (opens new window)
上次更新: 2020/12/17, 08:38:35