最开始我们RestTemplate,当时直连消费者和提供者,将请求路径写死在代码中,而且负载均衡只有自己手写,RestTemplate只能给我们提供远程调用的功能,后来我们加入了Eureka,作为一个中间人,利用Eureka的服务的注册发现和监控和负载均衡,通过Eureka客户端获取指定服务名的ip或者应用名+端口,动态拼接成url,外加上RestTemplate一起完成远程的调用,但你有没有发现RestTemplate这个包装类有点小问题,而且这样搞起来很麻烦
-
服务提供者有返回数据,但经过RestTemplate相关api的CRUD的API没有返回值为void
-
再者,分模块开发,我们根本不知道服务的提供者的返回值是什么,不可能一个一个的问
下面我们就要学习另一个组件取代RestTemplate,他就是OpenFeign
优雅的简单介绍
Feign的中文意思是伪装、装作的意思;OpenFeign是Feign的更新版本,是一种声明式REST客户端,使用起来听说更为便捷和优雅!Spring Boot1.X的时候就叫feign,我用的就是Feign;SpringCloud对Feign进行了增强,这个Feign也是那个租碟片公司研发的组件;
快速上手
首先是依赖问题,这里有点出入:
首先是第一个依赖肯定是要加的,后面两个依赖是后来百度异常信息加上的,方可运行
<!--openFeign的依赖 以下三个,不然抛出ClassNotFoundException-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
<dependency>
<groupId>com.netflix.archaius</groupId>
<artifactId>archaius-core</artifactId>
<version>0.7.6</version>
</dependency>
服务的提供者:无需改动
服务的消费者:
定义service接口,,这是Feign的核心所在,下面详细说明
package com.markyang.framework.client.system;
import com.markyang.framework.client.system.fallback.UserClientFallback;
import com.markyang.framework.pojo.auth.AuthenticatedUser;
import com.markyang.framework.pojo.dto.system.OrgUserDto;
import com.markyang.framework.pojo.web.ResultVo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import java.util.List;
/**
* client接口调用
* @author yangchangliang
*/
@Service
@FeignClient(name = "system", fallback = UserClientFallback.class)
public interface UserClient {
/**
* 根据用户名加载授权用户信息
* @param username 用户名
* @return 授权用户
*/
@GetMapping("/user/username/{username}")
ResultVo<AuthenticatedUser> getUserByUsername(@PathVariable String username);
/**
* 根据用户名加载授权用户信息
* @param phone 手机号
* @return 授权用户
*/
@GetMapping("/user/phone/{phone}")
ResultVo<AuthenticatedUser> getUserByMobilePhone(@PathVariable String phone);
/**
* 根据用户ID加载授权用户信息
* @param userId 用户ID
* @return 授权用户
*/
@GetMapping("/user/userId/{userId}")
ResultVo<AuthenticatedUser> getUserByUserId(@PathVariable String userId);
/**
* 获取所有的用户信息
* @param orgId 机构ID
* @return 结果对象
*/
@GetMapping("/user/orgUsers/{orgId}")
ResultVo<List<OrgUserDto>> getOrgUsers(@PathVariable String orgId);
}
-
首先这是一个接口,在服务的消费方,你可以把他当作Service层(偷懒)也可以当成Dao层
-
首先整体上来讲,Feign会通过动态代理帮我们生成实现类;
-
其次开局第一个注解@FeignClient,生命这是一个Feign客户端,同时通过value指定了服务提供者应用名
-
最后接口中定义的方法,方法是来自于服务提供者的service接口中的方法,但是方法上的注解确实来自服务提供者Controller上的注解,完全采用SpringMVC的注释,Feign会根据注解帮我们生成URL,并访问相应的服务接口
然后你可以在Controller层或者service层直接@Autowired这个接口,直接调用接口中的方法即可实现远程调用
然后还得在启动类上添加注解如下:
@SpringBootApplication
@EnableDiscoveryClient //开启Eureka客户端
@EnableFeignClients(basePackages = "xxxxxx") //开启Feign,并指定Service所在的包
public class ConsumerRun {
public static void main(String[] args) {
SpringApplication.run(ConsumerRun.class, args);
}
}
当然我的项目不写再启动类,具体可以移步个人的 spring cloud开源脚手架,快速上手开发
此外,Feign中还集成了Ribbon负载均衡,所以这里我们直接抛弃了RestTemplate,接下来把项目跑起来,通过我们的服务消费者远程调用服务提供者的api完成这次远程调用;说到这里,我们就必须得明白Ribbo了,下一篇我们就来学习一下