书籍地址: Spring Cloud 微服务架构开发实战
前面在我们使用RestTemplate调用其它微服务的API的时候, 所需要传入的参数必须在请求的URL中进行拼接. 如果参数很多…
拼接请求字符串, 低效且不易管理
但是,通过Feign
项目,我们就可以避免这个尴尬.
feign
是一个声明式的Web Service客户端,它的目的就是让 Web Service 调用更加简单
feign
提供了HTTP请求的模板,通过编写简单的接口并插入注解,就可以完成HTTP请求的参数,格式,地址等信息的声明. 通过Feign
代理HTTP请求,我们只需要像调用方法一样调用它就可以完成微服务请求及相关处理.
Feign
整合了Ribbon
和Hystrix
(Hystrix是啥,后续再说), 可以让我们不再需要显式的使用这两个组件.
Spring Cloud 还对 Feign
提供了SpringMVC注解的支持.
总结一下Feign
的特性:
Feign
注解和JAX-RS
注解.Hystrix
和它的回退功能.Ribbon
的负载均衡.Feign
1. pom.xml
接下来需要注意的是,我们在引入Feign
的时候, 如果你boot的版本是2.X,那么千万不要按照书上的引入依赖, 会报错,切记~
错误信息大致是这样的:ServerPropertiesAutoConfiguration cannot be opened because it does not exist
引入Feign
依赖的正确姿势:
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
<version>2.1.3.RELEASEversion>
dependency>
2. 启动类修改
@MapperScan("com.turnsole.productservice.mapper")
@EnableDiscoveryClient
@EnableFeignClients
@SpringBootApplication
public class ProductServiceApplication {
//创建一个RestTemplate Bean
// @Bean(value = "restTemplate")
// @LoadBalanced
// RestTemplate restTemplate(){
// return new RestTemplate();
// }
public static void main(String[] args) {
SpringApplication.run(ProductServiceApplication.class, args);
}
}
加入@EnableFeignClients 注解之后, 我们项目在启动时就具备了
Feign
环境,就可以使用Feign
进行微服务间的访问
3. 在用户微服务项目中添加一个 UserService的接口
@FeignClient("USERSERVICE")
public interface UserService {
/**
* 我们暂时只写测试用到的load方法
* 注意请求的mapping映射一定要与用户微服务所提供的一致
*/
@RequestMapping(value = "/users/{id}", method = RequestMethod.GET)
UserDto load(@PathVariable Integer id);
}
4. ProductCommentController 代码修改
//首先引入UserService,我们RestTemplate就用不上了
@Autowired
// @Qualifier(value = "restTemplate")
// private RestTemplate restTemplate;
private UserService userService;
//其次,在访问用户微服务的时候,通过userService的方法调用的形式进行访问
/**
* 通过指定商品id查询商品信息,评论者信息,评论内容
*/
@RequestMapping(value = "/{productId}/comments",method = RequestMethod.GET)
public List<ProductCommentDto> showMore(@PathVariable Integer productId){
ProductCommentParam param = new ProductCommentParam();
param.setProductId(productId);
PageResult<ProductComment> pq = productCommentService.getPageList(param, new PageQuery());
if (CollectionUtils.isEmpty(pq.getData())){
return Lists.newArrayList();
}
return pq.getData().stream().map((comment) -> {
ProductCommentDto dto = new ProductCommentDto();
dto.setComment(comment);
dto.setProduct(this.productService.loadOne(comment.getProductId()));
// 使用feign之后的改变之处
dto.setAuthor(this.userService.load(comment.getAuthorId()));
return dto;
}).collect(Collectors.toList());
}
5. 删除用不上的代码
6. 测试
百度了一波,发现网上没有多么好的答案,所以笔者打算带着这个疑问去学习接下来书中的知识,相信作者应该会给出答案.后续再回过头来补充.
7. 结束