微服务环境搭建
1. 案例准备
电商系统:搭建用户微服务,商品微服务,订单微服务
1.1 技术选型
maven:3.5+
数据库:mysql 5.7
持久层:MybatisPlus
其他:Spring Cloud Alibaba
1.2 模块设计
父工程:shop-parent
用户微服务:shop-user
商品微服务:shop-goods
订单微服务: shop-order
公共服务: shop-common
应用服务:shop-app
1.3 下单场景
用户下单,会涉及到用户微服务,商品微服务,订单微服务
1.4 搭建工程
1.4.1 创建父工程
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mszlu</groupId>
<artifactId>shop-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
</parent>
<packaging>pom</packaging>
<properties>
<!-- Spring Cloud -->
<spring.cloud.version>Hoxton.SR9</spring.cloud.version>
<!-- Apache Dubbo -->
<dubbo.version>2.7.8</dubbo.version>
<curator.version>4.0.1</curator.version>
<!-- Apache RocketMQ -->
<rocketmq.starter.version>2.0.2</rocketmq.starter.version>
<spring.cloud.alibaba>2.2.5.RELEASE</spring.cloud.alibaba>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<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>
</project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
1.4.2 创建common模块
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>shop-parent</artifactId>
<groupId>com.mszlu</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>shop-common</artifactId>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
</project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
统一返回类:
package com.mszlu.common;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Result<T> {
private boolean success;
private int code;
private String msg;
private T data;
public static <T> Result<T> success(T data) {
return new Result<>(true,200,"success",data);
}
public static <T> Result<T> fail(int code, String msg) {
return new Result<>( true,code,msg,null);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
1.4.3 创建用户微服务
1.4.3.1 XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>shop-parent</artifactId>
<groupId>com.mszlu</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>shop_user</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.mszlu</groupId>
<artifactId>shop-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
1.4.3.2 启动类
package com.mszlu.shop.user;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class UserApp {
public static void main(String[] args) {
SpringApplication.run(UserApp.class,args);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
1.4.3.3 配置文件
spring:
application:
name: shop-user
datasource:
password: root
username: root
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/shop?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
server:
port: 8001
mybatis-plus:
global-config:
db-config:
table-prefix: shop_
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1.4.3.4 User表
shop_user表:
CREATE TABLE `shop`.`shop_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`username` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`password` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`telephone` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`account` decimal(10, 2) NOT NULL COMMENT '账户',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
package com.mszlu.shop.user.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
//分布式id
@TableId(type = IdType.ASSIGN_ID)
private Long id;
private String username;
private String password;
private String telephone;
private BigDecimal account;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
1.4.4 创建商品微服务
1.4.4.1 XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>shop-parent</artifactId>
<groupId>com.mszlu</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>shop-goods</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.mszlu</groupId>
<artifactId>shop-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
1.4.4.2 启动类
package com.mszlu.shop.goods;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GoodsApp {
public static void main(String[] args) {
SpringApplication.run(GoodsApp.class);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
1.4.4.3 配置文件
spring:
application:
name: shop-goods
datasource:
password: root
username: root
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/shop?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
server:
port: 8002
mybatis-plus:
global-config:
db-config:
table-prefix: shop_
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1.4.4.4 商品表
shop_goods表:
CREATE TABLE `shop`.`shop_goods` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`goods_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '商品名称',
`goods_price` decimal(10, 2) NOT NULL COMMENT '商品价格',
`goods_stock` int(10) NOT NULL COMMENT '商品库存',
`create_time` bigint(20) NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
package com.mszlu.shop.goods.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class Goods {
@TableId(type = IdType.ASSIGN_ID)
private Long id;
private String goodsName;
private BigDecimal goodsPrice;
private Integer goodsStock;
private Long createTime;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1.4.5 创建订单微服务
1.4.5.1 XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>shop-parent</artifactId>
<groupId>com.mszlu</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>shop-order</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.mszlu</groupId>
<artifactId>shop-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
1.4.5.2 启动类
package com.mszlu.shop.order;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class OrderApp {
public static void main(String[] args) {
SpringApplication.run(OrderApp.class,args);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
1.4.5.3 配置文件
spring:
application:
name: shop-order
datasource:
password: root
username: root
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/shop?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
server:
port: 8003
mybatis-plus:
global-config:
db-config:
table-prefix: shop_
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1.4.5.4 订单表
shop_order表:
CREATE TABLE `shop`.`shop_order` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`order_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`user_id` bigint(20) NOT NULL,
`goods_id` bigint(20) NOT NULL,
`order_price` decimal(10, 2) NOT NULL,
`order_status` tinyint(4) NOT NULL,
`pay_status` tinyint(4) NOT NULL,
`pay_time` bigint(20) NOT NULL,
`create_time` bigint(20) NOT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
package com.mszlu.shop.order.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class Order {
@TableId(type = IdType.ASSIGN_ID)
private Long id;
private String orderId;
private Long userId;
private Long goodsId;
private BigDecimal orderPrice;
private Integer orderStatus;
private Integer payStatus;
private Long payTime;
private Long createTime;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
1.5 业务场景
下单服务:
前端传递用户id和商品id
- 判断用户是否存在以及账户是否有足够的金额
- 判断商品是否存在以及库存是否足够
- 生成订单
1.5.1 创建APP模块
1.5.1.1 XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>shop-parent</artifactId>
<groupId>com.mszlu</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>shop-app</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.mszlu</groupId>
<artifactId>shop-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1.5.1.2 配置文件
spring:
application:
name: shop-app
server:
port: 8004
1
2
3
4
5
2
3
4
5
1.5.1.3 启动类
package com.mszlu.shop.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class,args);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
1.5.2 用户微服务 提供用户查询服务
1.5.2.1 Dao层
package com.mszlu.shop.user.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan("com.mszlu.shop.user.mapper")
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.mszlu.shop.user.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mszlu.shop.user.pojo.User;
public interface UserMapper extends BaseMapper<User> {
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
1.5.2.2 Service层
package com.mszlu.shop.user.service;
import com.mszlu.common.Result;
public interface UserService {
Result findUser(Long id);
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
package com.mszlu.shop.user.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mszlu.common.Result;
import com.mszlu.common.user.UserBO;
import com.mszlu.shop.user.mapper.UserMapper;
import com.mszlu.shop.user.pojo.User;
import com.mszlu.shop.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public Result findUser(Long id) {
User user = userMapper.selectById(id);
if (user == null){
return Result.success(null);
}
UserBO userBO = new UserBO();
userBO.setAccount(user.getAccount());
userBO.setId(user.getId());
return Result.success(userBO);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
common模块下:
package com.mszlu.common.user;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class UserBO {
private Long id;
private BigDecimal account;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1.5.2.3 Controller
package com.mszlu.shop.user.controller;
import com.mszlu.common.Result;
import com.mszlu.shop.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("findUser/{id}")
public Result findUser(@PathVariable("id") Long id){
return userService.findUser(id);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1.5.3 商品微服务,提供商品查询服务
1.5.3.1 Dao层
package com.mszlu.shop.user.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan("com.mszlu.shop.goods.mapper")
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.mszlu.shop.goods.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mszlu.shop.goods.pojo.Goods;
public interface GoodsMapper extends BaseMapper<Goods> {
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
1.5.3.2 Service层
package com.mszlu.shop.goods.service;
import com.mszlu.common.Result;
public interface GoodsService {
Result findGoodsById(Long id);
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
package com.mszlu.shop.goods.service.impl;
import com.mszlu.common.Result;
import com.mszlu.common.goods.GoodsBO;
import com.mszlu.shop.goods.mapper.GoodsMapper;
import com.mszlu.shop.goods.pojo.Goods;
import com.mszlu.shop.goods.service.GoodsService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class GoodsServiceImpl implements GoodsService {
@Autowired
private GoodsMapper goodsMapper;
@Override
public Result findGoodsById(Long id) {
Goods goods = goodsMapper.selectById(id);
GoodsBO goodsBO = new GoodsBO();
BeanUtils.copyProperties(goods,goodsBO);
return Result.success(goodsBO);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.mszlu.common.goods;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class GoodsBO {
private Long id;
private String goodsName;
private BigDecimal goodsPrice;
private Integer goodsStock;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1.5.3.3 Controller层
package com.mszlu.shop.goods.controller;
import com.mszlu.common.Result;
import com.mszlu.shop.goods.service.GoodsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("goods")
public class GoodsController {
@Autowired
private GoodsService goodsService;
@GetMapping("findGoods/{id}")
public Result findGoods(@PathVariable("id") Long id){
return goodsService.findGoodsById(id);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1.5.4 订单微服务,提供生成订单服务
1.5.4.1 Dao层
package com.mszlu.shop.order.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan("com.mszlu.shop.order.mapper")
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.mszlu.shop.order.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mszlu.shop.order.pojo.Order;
public interface OrderMapper extends BaseMapper<Order> {
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
1.5.4.2 Service层
package com.mszlu.shop.order.service;
import com.mszlu.common.Result;
import com.mszlu.common.order.params.OrderParams;
public interface OrderService {
public Result createOrder(OrderParams orderParams);
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
package com.mszlu.shop.order.service.impl;
import com.mszlu.common.Result;
import com.mszlu.common.order.params.OrderParams;
import com.mszlu.shop.order.mapper.OrderMapper;
import com.mszlu.shop.order.pojo.Order;
import com.mszlu.shop.order.service.OrderService;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderMapper orderMapper;
@Override
public Result createOrder(OrderParams orderParams) {
Order order = new Order();
order.setCreateTime(System.currentTimeMillis());
order.setGoodsId(orderParams.getGoodsId());
order.setUserId(orderParams.getUserId());
order.setOrderPrice(orderParams.getGoodsPrice());
order.setOrderId(System.currentTimeMillis()+""+orderParams.getUserId()+ ""+RandomUtils.nextInt(1000,9999));
order.setOrderStatus(0);
order.setPayStatus(0);
order.setPayTime(-1L);
this.orderMapper.insert(order);
return Result.success(order.getOrderId());
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
1.5.4.3 Controller
package com.mszlu.shop.order.controller;
import com.mszlu.common.Result;
import com.mszlu.common.order.params.OrderParams;
import com.mszlu.shop.order.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("order")
public class OrderController {
@Autowired
private OrderService orderService;
@PostMapping("createOrder")
public Result createOrder(@RequestBody OrderParams orderParams){
return orderService.createOrder(orderParams);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1.5.5 下单业务
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
1
2
3
4
5
2
3
4
5
1.5.5.1 Controller
package com.mszlu.shop.app.controller;
import com.mszlu.common.Result;
import com.mszlu.shop.app.model.params.BuyParams;
import com.mszlu.shop.app.service.BuyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("buy")
public class BuyController {
@Autowired
private BuyService buyService;
@PostMapping("submit")
private Result submitOrder(@RequestBody BuyParams buyParams){
return buyService.submitOrder(buyParams);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.mszlu.shop.app.model.params;
import lombok.Data;
@Data
public class BuyParams {
private Long userId;
private Long goodsId;
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
1.5.5.2 Service
package com.mszlu.shop.app.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory requestFactory){
return new RestTemplate(requestFactory);
}
@Bean
public ClientHttpRequestFactory requestFactory(){
return new SimpleClientHttpRequestFactory();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.mszlu.shop.app.service;
import com.mszlu.common.Result;
import com.mszlu.shop.app.model.params.BuyParams;
public interface BuyService {
Result submitOrder(BuyParams buyParams);
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
package com.mszlu.shop.app.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.mszlu.common.Result;
import com.mszlu.common.goods.GoodsBO;
import com.mszlu.common.order.params.OrderParams;
import com.mszlu.common.user.UserBO;
import com.mszlu.shop.app.model.params.BuyParams;
import com.mszlu.shop.app.service.BuyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.math.BigDecimal;
import java.util.Map;
@Service
public class BuyServiceImpl implements BuyService {
@Autowired
private RestTemplate restTemplate;
@Override
public Result submitOrder(BuyParams buyParams) {
String userResult = restTemplate.getForObject("http://localhost:8001/user/findUser/" + buyParams.getUserId(), String.class);
Result<UserBO> userBOResult = JSON.parseObject(userResult,new TypeReference<Result<UserBO>>(){});
if (userBOResult == null || !userBOResult.isSuccess() || userBOResult.getData() == null){
return Result.fail(10001,"用户不存在");
}
UserBO userBO = userBOResult.getData();
String goodsResult = restTemplate.getForObject("http://localhost:8002/goods/findGoods/" + buyParams.getGoodsId(), String.class);
Result<GoodsBO> goodsBOResult = JSON.parseObject(goodsResult,new TypeReference<Result<GoodsBO>>(){});
if (goodsBOResult == null || !goodsBOResult.isSuccess() || goodsBOResult.getData() == null){
return Result.fail(10002,"商品不存在");
}
GoodsBO goodsBO = (GoodsBO) goodsBOResult.getData();
Integer goodsStock = goodsBO.getGoodsStock();
if (goodsStock < 0){
return Result.fail(10003,"商品库存不足");
}
BigDecimal goodsPrice = goodsBO.getGoodsPrice();
BigDecimal account = userBO.getAccount();
if (account.compareTo(goodsPrice) < 0){
return Result.fail(10004,"余额不足");
}
OrderParams orderParams = new OrderParams();
orderParams.setUserId(userBO.getId());
orderParams.setGoodsId(goodsBO.getId());
orderParams.setGoodsPrice(goodsBO.getGoodsPrice());
String orderResult = restTemplate.postForObject("http://localhost:8003/order/createOrder", orderParams, String.class);
Result<String> orderResultString = JSON.parseObject(orderResult,new TypeReference<Result<String>>(){});
if (orderResultString == null || !orderResultString.isSuccess()){
return Result.fail(10005,"下单失败");
}
String orderId = orderResultString.getData();
return Result.success(orderId);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
1.5.5.3 测试
{
"success": true,
"code": 200,
"msg": "success",
"data": "162384788039011376"
}
1
2
3
4
5
6
2
3
4
5
6
从上述的代码 可以看出,下单业务 调用各个微服务的时候 极其不方便。
一旦服务提供方 更改ip,端口,接口名称等,服务消费方 也需要跟着变
如果服务提供方有多台服务器呢?服务消费方还得需要维护这些ip信息,甚至自己实现负载均衡。
这时候 就需要 服务治理。