微服务架构编码构建

**约定>配置>编码**

1、构建父工程

1-1、创建项目

1-2、字符编码

1-3、注解生效激活

1-4、java编译版本选择:java8

1-5、父工程pom文件

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
<?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.jcvv.springcloud</groupId>
<artifactId>springCloud2023</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>


<!-- 统一管理 jar 包版本 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<junit.version>4.12</junit.version>
<log4j.version>1.2.17</log4j.version>
<lombok.version>1.16.18</lombok.version>
<mysql.version>5.1.47</mysql.version>
<druid.version>1.1.16</druid.version>
<mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
</properties>

<!-- 子块基础之后,提供作用:锁定版本 + 子module不用写 groupId 和 version -->
<dependencyManagement>
<dependencies>
<!-- 下面三个基本是微服务架构的标配 -->
<!--spring boot 2.2.2-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud Hoxton.SR1-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud 阿里巴巴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>

<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
<scope>runtime</scope>
</dependency>
<!-- druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.spring.boot.version}</version>
</dependency>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<!--log4j-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>

</dependencies>

</dependencyManagement>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
</project>
1-5-1、技术问题

问题一、

当导入完父类的pom文件时,会导入依赖失败

原因:maven仓库中不存在该依赖,dependencyManagement附庸于已存在的依赖

解决方案:把 标签去掉之后,填写依赖版本,下载完成后,在重新添加标签

问题二、

true爆红

解决方案:给pluin添加版本号 2.3.7.RELEASE


2、Rest微服务工程构建

2-1、创建支付模块moudle 8001

父pom变化

第一步:编写pom

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
<?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>springCloud2023</artifactId>
<groupId>com.jcvv.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-provider-payment8001</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 图形化显示-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<!--mysql-connector-java-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--jdbc-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</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>
</dependency>
</dependencies>
</project>

第二步:编写application.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
server:
port: 8001

spring:
application:
name: cloud-payment-service # 项目名,也是注册的名字

datasource:
type: com.alibaba.druid.pool.DruidDataSource #当前数据源操作类型
driver-class-name: org.gjt.mm.mysql.Driver #mysql驱动包
url: jdbc:mysql://localhost:3306/db2019?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
username: root
password: root

mybatis:
mapper-locations: classpath:mapper/*.xml
# 所有Entity 别名类所在包
type-aliases-package: com.jcvv.springcloud.entities

第三步:编写主启动类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.jcvv.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
* @Classname PaymentMain8001
* @Description chengzhi
* @Created by chengzhi
*/
@SpringBootApplication
public class PaymentMain8001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8001.class, args);
}
}

第四步:业务实现

1、建立SQL表(payment)

1
2
3
4
5
6
7
8
9
DROP DATABASE IF EXISTS springcloud2023
CREATE DATABASE springcloud2023;
USE springcloud2023;
CREATE TABLE `payment`(
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`serial` VARCHAR(200) DEFAULT '',
PRIMARY KEY (`id`)
)ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
SELECT * FROM payment;

2、创建实体entities

抽取entities实体类到该模块中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.jcvv.springcloud.entities;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
* @Classname CommonResult
* @Description chengzhi
* @Created by chengzhi
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult<T> {
private Integer code;
private String message;
private T data;
public CommonResult(Integer code,String message) {
this(code, message,null);
}
}

3、编写dao层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.jcvv.springcloud.dao;
import com.jcvv.springcloud.entities.Payment;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

/**
* @Classname PaymentDao
* @Description chengzhi
* @Created by chengzhi
*/
@Mapper
public interface PaymentDao {
public int create(Payment payment);
public Payment getPaymentById(@Param("id")long id);
}

编写mybatis映射文件PaymentMapper.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.jcvv.springcloud.dao.PaymentDao">

<insert id="create" parameterType="Payment" useGeneratedKeys="true" keyProperty="id">
insert into payment(serial)
values (#{serial});
</insert>
<resultMap id="BaseResultMap" type="com.jcvv.springcloud.entities.Payment">
<id column="id" property="id" jdbcType="BIGINT"></id>
<result column="serial" property="serial" jdbcType="VARCHAR"></result>
</resultMap>
<select id="getPaymentById" parameterType="Long" resultMap="BaseResultMap">
select *
from payment
where id = #{id};
</select>
</mapper>

4、编写service层

4.1、编写PaymentService

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.jcvv.springcloud.service;

import com.jcvv.springcloud.entities.Payment;
import org.apache.ibatis.annotations.Param;

/**
* @Classname PaymentService
* @Description chengzhi
* @Created by chengzhi
*/
public interface PaymentService {
public int create(Payment payment);
public Payment getPaymentById(@Param("id")long id);
}

4.2、编写PaymentServiceImpl

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
package com.jcvv.springcloud.service.impl;

import com.jcvv.springcloud.dao.PaymentDao;
import com.jcvv.springcloud.entities.Payment;
import com.jcvv.springcloud.service.PaymentService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
* @Classname PaymentServiceImpl
* @Description chengzhi
* @Created by chengzhi
*/
@Service
public class PaymentServiceImpl implements PaymentService {
@Resource
private PaymentDao paymentDao;
@Override
public int create(Payment payment) {
return paymentDao.create(payment);
}

@Override
public Payment getPaymentById(long id) {
return paymentDao.getPaymentById(id);
}
}

5、编写controller层

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
package com.jcvv.springcloud.controller;

import com.jcvv.springcloud.entities.CommonResult;
import com.jcvv.springcloud.entities.Payment;
import com.jcvv.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
* @Classname PaymentController
* @Description chengzhi
* @Created by chengzhi
*/
@RestController
@Slf4j
public class PaymentController {
@Resource
private PaymentService paymentService;

@PostMapping(value = "/payment/create")
public CommonResult create(@RequestBody Payment payment) {
int result = paymentService.create(payment);
log.info("*******插入结果" + result);
if (result > 0) {
return new CommonResult(200, "插入数据成功!", result);

} else {
return new CommonResult(444, "插入数据失败", null);
}
}

@GetMapping(value = "/payment/get/{id}")
public CommonResult getPaymentById(@PathVariable("id") Long id) {
Payment payment = paymentService.getPaymentById(id);
log.info("*******插入结果" + payment);
if (payment !=null) {
return new CommonResult(200, "查询成功!", payment);

} else {
return new CommonResult(444, "查询失败,没有对应记录", null);
}
}
}

6、接口测试

2-2、热加载

1、方式一、DevTools

1、导入依赖

1
2
3
4
5
6
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>

2、方式二、热加载之JRebel

安装JRebel

1、在IDEA中一次点击 File->Settings->Plugins->Brows Repositories
2、在搜索框中输入JRebel进行搜索
3、找到JRebel for intellij
4、install
5、安装好之后需要restart IDEA

激活

JRebel并非免费的插件,需要激活之后才能使用。
1、首先到github上去下载一个反向代理软件,我下载的是windows x64版本。

下载地址

2、双击运行我们下载的程序

3、激活JRebel配置信息

第一行输入 http://127.0.0.1:8888/d3545f42-7b88-4a77-a2da-5242c46d4bc2
第二行输入正确的邮箱格式,例如: test@123.com
勾选同意协议,再点击Activate JRebel 按钮验证激活
提示:d3545f42-7b88-4a77-a2da-5242c46d4bc2为UUID,可以自己生成,并且必须是UUID才能通过验证

4、之后还会弹出来页面,相信你能应付。最后别忘了把JRebel设置为offline模式 点一下work offline

3、进行系统设置

1、settings配置打勾

2、打开父类pom文件

按ctrl+alt+shift+/ 弹出窗口,然后进入Registry ,勾选自动编译 -> compiler.automake.allow.when.app.running

3、重启IDEA

2-3、创建消费者订单模块moudle

第一步:创建模块

创建模块cloud-consumer-order80

第二步 :导入依赖

导入依赖(此处俺被坑了,没有用到的mybatis和数据库依赖不到导入,不然运行会出错)

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
<?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>springCloud2023</artifactId>
<groupId>com.jcvv.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>cloud-consumer-order80</artifactId>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 图形化显示-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- devtools-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-devtools</artifactId>-->
<!-- <scope>runtime</scope>-->
<!-- <optional>true</optional>-->
<!-- </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>
</dependency>
</dependencies>
</project>

第三步:编写application.yml

编写application.yml文件

1
2
server:
port: 80

第四步:编写主启动类

编写主启动类

com.jcvv.springcloud.OrderMain80

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.jcvv.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
* @Classname OrderMain80
* @Description chengzhi
* @Created by chengzhi
*/
@SpringBootApplication
public class OrderMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderMain80.class);
}
}

第五步业务实现

业务实现

1、编写实体类

Payment

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.jcvv.springcloud.entities;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
* @Classname Payment
* @Description chengzhi
* @Created by chengzhi
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Payment implements Serializable {
private Long id;
private String serial;
}

CommonResult

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.jcvv.springcloud.entities;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
* @Classname CommonResult
* @Description chengzhi
* @Created by chengzhi
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult<T> {
private Integer code;
private String message;
private T data;
public CommonResult(Integer code,String message) {
this(code, message,null);
}
}

2、controller层
3、RestTemplate介绍

RestTemplate提供了多种便捷访问远程Http服务的方法, 是一种简单便捷的访问restful服务模板类,是Spring提供的用于访问Rest服务的客户端模板工具集。

官方网址:https://docs.spring.io/spring-framework/docs/5.2.2.RELEASE/javadoc-api/org/springframework/web/client/RestTemplate.html

使用

使用restTemplate访问restful接口非常的简单粗暴无脑。(url, requestMap, ResponseBean.class)这三个参数分别代表 REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。

config配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.jcvv.springcloud.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
* @Classname ApplicationContextConfig
* @Description chengzhi
* @Created by chengzhi
*/
@Configuration
public class ApplicationContextConfig {
@Bean
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}

4、controller类
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
package com.jcvv.springcloud.controller;

import com.jcvv.springcloud.entities.CommonResult;
import com.jcvv.springcloud.entities.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

/**
* @Classname OrderController
* @Description chengzhi
* @Created by chengzhi
*/
@RestController
@Slf4j
public class OrderController {
public static final String PAYMENT_URL = "http://localhost:8001";
@Resource
private RestTemplate restTemplate;

/**
* @param payment
* @return
*/
@GetMapping("/consumer/payment/create")
public CommonResult<Payment> create(Payment payment) {
//payment 参数,CommonResult.class返回类型
return restTemplate.postForObject(PAYMENT_URL + "/payment/create", payment, CommonResult.class);

}

/**
*
* @param id
* @return
*/
@GetMapping("/consumer/payment/get/{id}")
public CommonResult<Payment> getPayment(@PathVariable("id") Long id) {
return restTemplate.getForObject(PAYMENT_URL + "/payment/get/" + id, CommonResult.class);
}
}

2-4、使用Run Dashboard

第一步:

第二步:

第三步:选择springboot即可

ps:如果上述列表找不到Run Dashboard,则可以在工程目录下找到.idea文件夹下的workspace.xml,在其中相应位置加入以下代码(替换)即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<component name="RunDashboard">
<option name="configurationTypes">
<set>
<option value="SpringBootApplicationConfigurationType"/>
</set>
</option>
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule"/>
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule"/>
</RuleState>
</list>
</option>
</component>

2-5、工程重构

1、创建模块cloud-api-common

2、导入pom文件

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
<?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>springCloud2023</artifactId>
<groupId>com.jcvv.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>cloud-api-common</artifactId>

<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!-- devtools-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-devtools</artifactId>-->
<!-- <scope>runtime</scope>-->
<!-- <optional>true</optional>-->
<!-- </dependency>-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 工具包,功能有时间转换...-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.1.0</version>
</dependency>
</dependencies>
</project>

3、抽取entities实体类到该模块中

相关链接:Eureka服务注册中心😶