在这里为了演示微服务间的远程调用,在这里就要设定需求场景了,先看原来demo的功能:
先看一下两个微服务间需要交互的功能接口,这里的小demo只有一个,那就是查询订单的接口
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
public Order queryOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
return order;
}
}
接下来启动服务,咱们看一下控制台返回的数据
从上面,可以很清晰地看到user是空的,那么我们查询订单的时候想让它显示对应的user信息怎么办呢?
这个时候,订单查询模块的接口就需要远程调用user模块的查询接口得到相应的user信息了。
那么,不同模块之间的怎么调用其他模块的接口呢?
有了这些疑问,接下来,大家跟着风哥一起探索一下吧。
2.2 案例需求
在做一个功能时,我们的大体思路都是先确定需求,画好流程图,然后讨论,明确需求,再去实施,微服务同样也不例外。
接下来,咱们看一下各个模块相互间的功能需求图,咱们这个小demo及其简单,微服务间的接口间的相互调用只有order-service中的查询接口的方法内去调用user-service中的查询接口,来,看需求图。
看了需求图,相信大家对过程有了一个更清晰的了解,也明白接下来咱们需要做什么了,没错,我上句话已经说过了,order-service模块中的查询方法要向user-service模块发送一个http请求,调用http://localhost:8081/user/{userId}这个接口,获得相应的用户信息。
然而呢,比较细心的小伙伴们,相信已经发现了现在风哥好像还没有说通过调用用户模块查询接口获取用户数据返回的数据类型是什么?有的人肯定会说,那肯定是User类型啊。这样说没错,但是说明咱们欠缺了思考,从另一个模块的接口获得数据,你这个模块里又没有相应的数据类型,你怎么将人家的数据封装成User类型呢?而这也恰恰是咱们需要学习远程调用中的一个关键部分。带着疑问出发学习更有劲,那么,跟着风哥来看一下具体的步骤吧。
大概步骤:
- 注册一个RestTemplate的实例并注入到Spring容器中取
- 在order-service中修改OrderService类中的queryOrderById方法,根据Order对象中的userid查询user数据
- 在OrderService类中注入RestTemplate的实例对象,通过调用它的getForObject()方法将指定url的数据封装成指定类型的数据
- 将封装的User对象加入到Order对象中去,返回Order对象
来,小伙伴们跟着风哥的步骤一起来做一下,let’s go.
步骤一 在order模块的启动类注册RestTemplate对象
为什么选择在order模块的启动类中呢,因为在这个过程中,order模块的相应方法是一个消费者行为,user模块充当的是一个服务者行为,而关于消费者和服务者理论,我会放在文末进行描述。
@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
/\*\*
\* 为了实现负载均衡
\* 创建RestTemplate并注入Spring容器中
\* @return
\*/
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
步骤二 调用相应接口获取并封装数据
在这里,我把细分的2-4步合并为了一步,因为实现起来,不要问:风哥,为啥呢?因为它俩密不可分呐,拆开来描述是为了让大家更清晰地去了解具体流程,而现在实现则要根据实际情况啊,宝贝儿们。
- 这里我为什么url前面用的是userservice,而不是其微服务模块对应的端口呢,这就涉及了Eureka的知识了,在这里没改是为了给大家先埋下个种子,让大家充满干劲去看本专栏下篇文章
- restTemplate.getForObject(url, User.class):通过url调用相应的接口获取数据并封装成User数据类型
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private RestTemplate restTemplate;
public Order queryOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
//2.查询user
//2.1.获取url地址
String url = "http://userservice/user/"+order.getUserId();
//2.2.根据url发起远程调用获取user
User user = restTemplate.getForObject(url, User.class);
//3.设置用户
order.setUser(user);
// 4.返回
return order;
}
}
最后返回所需要的order数据类型即可。
结果图
2.3 服务者和消费者
前面说好的哈,文末跟大家聊一聊服务者和消费者理论。
在服务调用关系中,都有两个不同的角色:
- 服务者:即服务的提供方,说的现实一点,就是乙方啊😂
- 消费者:调用服务的一方,也说现实一点,就是甲方啊😂
在咱们这个小案例demo中,服务者和消费者非常清晰。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!