在微服务架构中,最常见的场景就是微服务直接互相调用,下面我们以电商系统中常见的用户下单为例子进行演示微服务之间的调用,用户向订单微服务发起一个下单的请求,在进行保存订单之前需要调用商品微服务查询商品的信息
思路:用户下单,首先根据要下单的商品去查询商品是否存在,存在的话才能操作,也就是传一个pid(商品id),商品微服务收到请求会如果商品存在会返回一个商品实体类,也就是说订单微服务只需要一个传pid参数的查询方法,商品微服务需要一个返沪商品信息的方法
开始编写product商品的代码
dao
package com.wyh.dao;
import com.wyh.entity.Order;
import com.wyh.entity.Product;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* @program: springcloud-alibaba
* @description: Product dao接口
* @author: 魏一鹤
* @createDate: 2022-05-01 22:54
**/
//根据jpa规范实现JpaRepository接口 有两个泛型 分别是实体类和id的数据类型
public interface ProductDao extends JpaRepository<Product,Integer> {
}
service
package com.wyh.service;
import com.wyh.entity.Product;
/**
* @program: springcloud-alibaba
* @description: Product service
* @author: 魏一鹤
* @createDate: 2022-05-01 22:53
**/
public interface ProductService {
//根据pid查询商品信息
Product findProductByPid(Integer pid);
}
serviceImpl
package com.wyh.service.impl;
import com.wyh.dao.ProductDao;
import com.wyh.entity.Product;
import com.wyh.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @program: springcloud-alibaba
* @description: Product service实现类
* @author: 魏一鹤
* @createDate: 2022-05-01 22:53
**/
@Service
public class ProductServiceImpl implements ProductService {
//注入商品product dao接口
@Autowired
ProductDao productDao;
@Override
public Product findProductByPid(Integer pid) {
//这个findById方法是jpa提供的不是我们写的 需要通过get获取 不然会报错
return productDao.findById(pid).get();
}
}
controller
package com.wyh.controller;
import com.alibaba.fastjson.JSON;
import com.wyh.entity.Product;
import com.wyh.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* @program: springcloud-alibaba
* @description: Product controller
* @author: 魏一鹤
* @createDate: 2022-05-01 22:52
**/
@RestController
//打印日志的注解 由lombok提供
@Slf4j
public class ProductController {
//注入product商品服务层接口
@Resource
private ProductService productService;
//根据商品id进行商品信息查询 restful接口
@RequestMapping("/product/{pid}")
public Product findProduct(@PathVariable("pid") Integer pid) {
//日志打印信息 pid可以放入到{}进行参数占位
log.info("接下来要进行{}号信息的查询",pid);
Product product=productService.findProductByPid(pid);
log.info("商品信息查询成功,内容为{}", JSON.toJSONString(product));
return product;
}
}
拼接日志如下
首先在数据库创建shop这个数据库,如果没有创建会报下面这个错
开始编写order订单的代码
package com.wyh.dao;
import com.wyh.entity.Order;
import com.wyh.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* @program: springcloud-alibaba
* @description: Order dao接口
* @author: 魏一鹤
* @createDate: 2022-05-01 22:54
**/
//根据jpa规范实现JpaRepository接口 有两个泛型 分别是实体类和id的数据类型
public interface OrderDao extends JpaRepository<Order,Integer> {
}
package com.wyh.dao;
import com.wyh.entity.Order;
import com.wyh.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* @program: springcloud-alibaba
* @description: Order dao接口
* @author: 魏一鹤
* @createDate: 2022-05-01 22:54
**/
//根据jpa规范实现JpaRepository接口 有两个泛型 分别是实体类和id的数据类型
public interface OrderDao extends JpaRepository<Order,Integer> {
}
package com.wyh.service.impl;
import com.wyh.dao.OrderDao;
import com.wyh.entity.Order;
import com.wyh.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @program: springcloud-alibaba
* @description: Order service实现类
* @author: 魏一鹤
* @createDate: 2022-05-01 22:53
**/
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderDao orderDao;
@Override
public void createOrder(Order order) {
//这个dao的save方法是jpa提供的
orderDao.save(order);
}
}
package com.wyh.controller;
import com.alibaba.fastjson.JSON;
import com.wyh.entity.Order;
import com.wyh.entity.Product;
import com.wyh.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* @program: springcloud-alibaba
* @description: order controller
* @author: 魏一鹤
* @createDate: 2022-05-01 22:52
**/
@RestController
@Slf4j
public class OrderController {
@Autowired
private OrderService orderService;
@Autowired
private RestTemplate restTemplate;
//下单
@RequestMapping("/order/prod/{pid}")
public Order order(@PathVariable Integer pid) {
log.info("接收到{}号商品的下单请求,接下来调用商品微服务查询此商品信息",pid);
//调用商品微服务查询商品信息
//使用用restTemplate调用商品微服务 有两个参数 url访问地址和返回值
Product product = restTemplate.getForObject("http://localhost:8081/product/" + pid, Product.class);
log.info("查询到{}号商品信息,内容是{}",pid, JSON.toJSONString(product));
//组装order订单信息
Order order=new Order();
//用户信息 模拟即可
order.setUid(1);
order.setUsername("测试用户");
//商品信息 从查询到的product中获取
order.setPid(pid);
order.setPname(product.getPname());
order.setPprice(product.getPprice());
//购买数量 模拟即可
order.setNumber(1);
//下单 创建订单信息
orderService.createOrder(order);
log.info("创建信息成功,订单信息为:{}",JSON.toJSONString(order));
return order;
}
}
orderApplication 需要通过RestTemplate进行调用其他消费者
package com.wyh;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
/**
* @program: springcloud-alibaba
* @description: order启动类
* @author: 魏一鹤
* @createDate: 2022-05-01 23:00
**/
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args){
SpringApplication.run(OrderApplication.class);
}
//把restTemplate注入到spring并且使用restTemplate调用微服务
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
启动订单微服务测试代码,因为涉及到商品微服务,所以商品微服务启动类也要跑起来
下单正常
至此两个微服务之间的简单调用以及下单就完成了!
有两个名词需要注意,后面也会频繁出现
主动消费的一方叫做服务消费者,被消费的一方叫做服务提供者