微服务最重要的一个功能是服务间调用,各个服务互相依赖。比如电商系统有订单服务,有库存服务。在我们购买一件商品的时候,需要生成订单和减库存。这里我们就要用到服务间调用Feign。
Feign是一个http请求调用的轻量级框架,可以以Java接口注解的方式调用Http请求,而不用像Java中通过封装HTTP请求报文的方式直接调用。
接下来我们新建两个module,一个app-order,一个app-storage;app-order作为调用方,app-storage作为被调用方。使用mybatis-plus作为数据处理框架。使用lombok简化代码(idea需要按照lombok插件,否则会报错)
1. 创建app-storage
1.1 修改app-storage下的pom.xml文件
<properties> <java.version>1.8</java.version> <spring-cloud.version>Hoxton.SR1</spring-cloud.version></properties><dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- eureka-client --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!-- feign --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!-- mybatis-plus --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.3.1.tmp</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency></dependencies><dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies></dependencyManagement>
1.2 修改配置
# 设置端口号server.port=9920# 设置服务名称spring.application.name=app-storage# 设置eurekaeureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/eureka.instance.instance-id=${spring.application.name}:${server.port}# 数据源配置spring.datasource.url=jdbc:mysql://localhost:3306/storage?allowMultiQueries=true&serverTimezone=GMT%2B8&useSSL=false&allowPublicKeyRetrieval=truespring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.username=rootspring.datasource.password=root
1.3 创建表,预制数据
CREATE TABLE `tb_storage` ( `id` int(11) NOT NULL AUTO_INCREMENT, `commodity_code` varchar(255) DEFAULT NULL, `count` int(11) DEFAULT 0, PRIMARY KEY (`id`), UNIQUE KEY (`commodity_code`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
预制数据
INSERT INTO `storage`(`id`, `commodity_code`, `count`) VALUES (1, 'product-1', 9999999);
1.4 修改启动类
@SpringBootApplication@EnableEurekaClient // 开启eureka客户端模式@MapperScan("com.ipp.springcloud.appstorage.mapper") // mybatis扫描public class AppOrderApplication { public static void main(String[] args) { SpringApplication.run(AppOrderApplication.class, args); }}
1.5 创建storage表对应的entity,mapper,service,controller
可以用mybatis-plus代码生成插件去生成以上代码,篇幅问题不在此处做详细展示,详细内容请查看git仓库。
1.6 创建一个供app-order调用的减库存接口
controller
/** * 减库存 * @param commodityCode 商品代码 * @param count 数量 * @return */ @RequestMapping(path = "/deduct") public Boolean deduct(String commodityCode, Integer count) { storageService.deduct(commodityCode, count); return true; }
service
@Override public void deduct(String commodityCode, int count) { QueryWrapper<Storage> wrapper = new QueryWrapper<>(); wrapper.setEntity(new Storage().setCommodityCode(commodityCode)); Storage storage = baseMapper.selectOne(wrapper); storage.setCount(storage.getCount() - count); baseMapper.updateById(storage); }
2. 创建app-order
2.1 修改app-order下的pom.xml文件
内容与app-storage一致
2.2 修改配置
# 设置端口号server.port=9910# 设置服务名称spring.application.name=app-order# 设置eurekaeureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/eureka.instance.instance-id=${spring.application.name}:${server.port}# 数据源配置spring.datasource.url=jdbc:mysql://localhost:3306/order?allowMultiQueries=true&serverTimezone=GMT%2B8&useSSL=false&allowPublicKeyRetrieval=truespring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.username=rootspring.datasource.password=root
2.3 创建表
CREATE TABLE `tb_order` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` varchar(255) DEFAULT NULL, `commodity_code` varchar(255) DEFAULT NULL, `count` int(11) DEFAULT 0, `money` int(11) DEFAULT 0, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2.4 修改启动类
@SpringBootApplication@EnableEurekaClient // 开启eureka客户端模式@EnableFeignClients //开启feign请求@MapperScan("com.ipp.springcloud.apporder.mapper") // mybatis扫描public class AppOrderApplication { public static void main(String[] args) { SpringApplication.run(AppOrderApplication.class, args); }}
2.5 创建表order表对应的entity,mapper,service,controller
可以用mybatis-plus代码生成插件去生成以上代码,篇幅问题不在此处做详细展示,详细内容请查看git仓库。
2.6 创建feign调用接口
@FeignClient(name = "APP-STORAGE")public interface StorageFeignService { /** * 减库存 * @param commodityCode * @param count * @return */ @GetMapping("storage/deduct") Boolean deduct(@RequestParam("commodityCode") String commodityCode, @RequestParam("count") Integer count);}
这里的@FeignClient 中的name写的是app-storage服务的服务名称(也就是注册到eureka中的服务名称)
下面声明的deduct方法对应app-storage服务中的deduct接口
2.7 创建下订单的接口
controller
@RequestMapping("/placeOrder/commit") public Boolean placeOrderCommit() { orderServiceImpl.placeOrder("1", "product-1", 1); return true; }
service
@Autowiredprivate StorageFeignService storageFeignService;@Overridepublic void placeOrder(String userId, String commodityCode, Integer count) { BigDecimal orderMoney = new BigDecimal(count).multiply(new BigDecimal(5)); Order order = new Order() .setUserId(userId) .setCommodityCode(commodityCode) .setCount(count) .setMoney(orderMoney); baseMapper.insert(order); storageFeignService.deduct(commodityCode, count);}
3. 启动服务验证
依次启动server-eureka,app-storage,app-order
4. 验证接口
在浏览器中访问 http://127.0.0.1:9910/order/placeOrder/commit , 分别查看order表和storage表。是否生成了订单和减了库存
本文分享自微信公众号 - 自增程序员(javaipp)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。