本期目录
- 1. 情景
- 2. 远程调用方式分析
- 3. 远程调用步骤
- 3.1 注册 RestTemplate
- 3.2 修改订单业务层
- 3.3 测试
- 4. 总结
1. 情景
-
我编写的订单微服务查询订单时,无法跨越数据库查询订单所关联的用户
user
。因此下图中订单数据的user
字段为null
。 -
本节,我们将演示订单微服务
order-service
如何通过远程调用用户微服务user-service
的根据用户 ID 查询用户的接口,来查询订单的同时,把订单所属的用户信息一起返回,如下图所示。
2. 远程调用方式分析
-
订单微服务
order-service
也可以像浏览器一样,向用户微服务user-service
发起 HTTP 请求,那么用户微服务就响应对应的用户信息给订单微服务。订单微服务获取到用户数据后,再结合本地的订单数据库查询出的订单数据,就组合出了订单及其所属的用户信息。因此,现在的问题的核心就变成了:如何在 Java 代码中发起 HTTP 请求?
3. 远程调用步骤
3.1 注册 RestTemplate
-
RestTemplate
是 Spring 提供的发起 HTTP 请求的工具类。 -
首先,我们要在订单微服务
order-service
的OrderApplication.java
应用启动类中注册RestTemplate
。这样,将来我们就可以在任何地方注入RestTemplate
对象来使用。@MapperScan("cn.itcast.order.mapper") @SpringBootApplication @Slf4j public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); log.info("订单微服务启动成功"); } // 注册RestTemplate,用来发起HTTP请求远程调用 @Bean public RestTemplate restTemplate() { return new RestTemplate(); } }
【小贴士】
@Bean
的注入只能放在 Spring 的配置类中。而启动类OrderApplication.java
带有注解@SpringBootApplication
本身也是配置类。因此,可以在启动类中写@Bean
的注入。
3.2 修改订单业务层
-
订单的实体类
Order.java
中,有用户 ID 的字段userId
。因此我们可以根据字段userId
向用户微服务发起 HTTP 请求。首先把RestTemplate
自动注入进来。 -
然后,如果你要发 GET 请求,就使用
getForObjct()
方法。其中,第一个入参URI url
就跟浏览器向用户微服务发起的 HTTP 请求地址是一样的,如http://localhost:8081/user/1
;第二个入参responseType
指的是返回值类型,RestTemplate
非常智能,正常情况下,HTTP 请求后得到的返回值一般都是 JSON 风格的字符串,但这第二个入参responseType
指定后,RestTemplate
就会自动地帮我们把 JSON 数据反序列化成你指定的 Java 实体类对象。 -
OrderService.java
:@Service public class OrderService { @Autowired private OrderMapper orderMapper; // 自动注入RestTemplate,用于发起HTTP请求远程调用 @Autowired private RestTemplate restTemplate; public Order queryOrderById(Long orderId) { // 1.查询订单 Order order = orderMapper.findById(orderId); // 2.使用RestTemplate发起HTTP请求,查询订单所属用户信息 // 2.1 根据查询的订单order中的userId动态生成HTTP请求的url String url = "http://localhost:8081/user/" + order.getUserId(); // 2.2 发送HTTP请求,实现远程调用 User user = restTemplate.getForObject(url, User.class); // 3.把远程调用获得的user封装进order对象中 order.setUser(user); // 4.返回order订单信息 return order; } }
3.3 测试
-
重启两个微服务,用 Postman 向订单微服务发送根据订单 ID 查询的请求。
这样,我们就成功使用
RestTemplate
实现了跨服务的远程调用。
4. 总结
- 基于 Spring 提供的
RestTemplate
可以发起 HTTP 请求实现微服务之间的远程调用。 - HTTP 请求做远程调用是与语言无关的调用,只要知道对方的 IP 、端口、接口路径和请求参数即可。