03Rest微服务搭建案例工程模块
一、微服务架构模块
1. 总体介绍
- 使用SpringBoot+SpringMVC+Mybatis+Mysql技术,以dept部门做一个微服务的案例。Consumer消费者(Client)通过Rest调用Provider提供者(Server)提供的服务。
- Maven的分包分模块的架构,一个父工程(Project)带着多个模块(Module)子模块
2. 工程的结构
springcloud-dept---------------父工程(Project)
springcloud-common------------封装的整体entity/接口/公共配置等(Module)
springcloud-provider-8001-----微服务的服务提供者(Module)
springcloud-consumer-80-------微服务调用的客户端使用,80端口(Module)
二、SpringCloud与Springboot的版本
1. Springboot版本
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
2. SpringCloud版本
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
SpringCloud的版本号问题:
- SpringCloud版本用的是单词而不是数字,为了更好的管理每个SpringCloud子项目的清单,避免自己的版本号与子项目的版本号混淆。
- 使用英国伦敦地铁站的名称来命名,首字母越靠后表示版本号越大。
关于版本发布说明:
- BUILD-XXX 开发版,开发团队内部使用,不是很稳定
- GA 稳定版,相比于开发版,基本上可以使用了
- PRE(M1、M2) 里程碑版,主要是修复了一些BUG的版本,一个GA后通常有多个里程碑版
- RC 候选发布版,该阶段的软件类似于最终版的一个发行观察期,基本只修复比较严重的BUG
- SR 正式发布版
三、父工程springcloud-dept
1. 创建项目
不选择原型(archetype)创建maven项目
GroupId为com.springboot,ArtifactId为springcloud-dept
2. pom.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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.springcloud</groupId>
<artifactId>springcloud-dept</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 将打包方式修改为pom模式 -->
<packaging>pom</packaging>
<properties>
<cloud.version>Greenwich.SR2</cloud.version>
<boot.version>2.1.6.RELEASE</boot.version>
<mybatis.version>2.0.1</mybatis.version>
<mysql.version>5.1.38</mysql.version>
<druid.version>1.1.10</druid.version>
<lombok.version>1.18.6</lombok.version>
<log4j.version>1.2.17</log4j.version>
<junit.version>4.12</junit.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
四、公共模块springcloud-common
1. 创建模块
选中父工程右键点击—>New—>Module
父工程中出现子模块
父工程的pom文件发生变化
<modules>
<module>springcloud-common</module>
</modules>
2. pom.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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.springcloud</groupId>
<artifactId>springcloud-dept</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>springcloud-common</artifactId>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
3. 部门实体类
结合使用lombok新建部门实体类Dept
@NoArgsConstructor
@AllArgsConstructor
@Data
//链式访问的风格
@Accessors(chain=true)
public class Dept {
//主键
private Integer deptno;
//部门名称
private String dname;
//来自哪个数据库,因为微服务架构可以一个服务连接独立的一个数据库,同一个信息可以存储到不同的数据库中
private String dbSource;
}
4. Maven install
Maven Clean/Maven install后给其他的模块引用,达到通用的目的。需要用到部门实体,不用在工程中定义一份,可直接引用本模块就可以了。
五、微服务提供者模块springcloud-provider-8001
1. 创建模块
2. pom.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>
<groupId>com.springcloud</groupId>
<artifactId>springcloud-dept</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springcloud-provider-8001</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-test</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!-- 引入自己定义的公共模块,可以使用Dept部门实体类 -->
<dependency>
<groupId>com.springcloud</groupId>
<artifactId>springcloud-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
</project>
3. application.yml
server:
port: 8001
mybatis:
# mybatis配置核心文件位置
# config-location: classpath:mybatis/mybatis-config.xml
# 类型别名所在包
type-aliases-package: com.springcloud.entity
# mapper映射文件位置
mapper-locations: classpath:mybatis/mapper/**/*.xml
# 下划线转驼峰
configuration:
map-underscore-to-camel-case: true
spring:
# 数据源
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/cloudDB01
username: root
password: 123456
4. MyBatis核心配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
</configuration>
5. 创建数据库Dept表
DROP DATABASE IF EXISTS cloudDB01;
CREATE DATABASE cloudDB01 CHARACTER SET UTF8;
USE cloudDB01;
CREATE TABLE dept
(
deptno BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
dname VARCHAR(60),
db_source VARCHAR(60)
);
INSERT INTO dept(dname,db_source) VALUES('研发部',DATABASE());
INSERT INTO dept(dname,db_source) VALUES('人事部',DATABASE());
INSERT INTO dept(dname,db_source) VALUES('财务部',DATABASE());
INSERT INTO dept(dname,db_source) VALUES('市场部',DATABASE());
INSERT INTO dept(dname,db_source) VALUES('运维部',DATABASE());
6. Dao层
6.1 Dao接口
@Mapper
public interface DeptDao {
boolean insertDept(Dept dept);
Dept selectOneDept(Integer id);
List<Dept> selectDept();
}
6.2 Mapper映射文件
在src/main/resources目录下建立mybatis/mapper子目录,并创建DeptMapper.xml文件
<?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.springcloud.dao.DeptDao">
<insert id="insertDept" parameterType="Dept">
insert into dept(dname,db_source) values(#{dname},database())
</insert>
<select id="selectOneDept" parameterType="int" resultType="Dept">
select deptno,dname,db_source from dept where deptno=#{deptno}
</select>
<select id="selectDept" resultType="Dept">
select deptno,dname,db_source from dept
</select>
</mapper>
7. Service层
7.1 Service接口
public interface DeptService {
boolean addDept(Dept dept);
Dept getDept(Integer id);
List<Dept> listDept();
}
7.2 Service实现类
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptDao deptDao;
@Override
public boolean addDept(Dept dept) {
return deptDao.insertDept(dept);
}
@Override
public Dept getDept(Integer id) {
return deptDao.selectOneDept(id);
}
@Override
public List<Dept> listDept() {
return deptDao.selectDept();
}
}
8. Controller层
@RestController
@RequestMapping("/dept")
public class DeptController {
@Resource
private DeptService deptService;
@GetMapping("/list")
public List<Dept> listDept(){
return deptService.listDept();
}
@GetMapping("/get/{id}")
public Dept getDept(@PathVariable("id") Integer id){
return deptService.getDept(id);
}
@PostMapping("/add")
public boolean addDept(@RequestBody Dept dept){
return deptService.addDept(dept);
}
}
9. 主启动类
@SpringBootApplication
public class DeptProvider8001Application {
public static void main(String[] args) {
SpringApplication.run(DeptProvider8001Application.class, args);
}
}
10. 测试
http://localhost:8001/dept/get/1
http://localhost:8001/dept/list
六、微服务消费者模块springcloud-consumer-80
1. 创建模块
2. pom.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>
<groupId>com.springcloud</groupId>
<artifactId>springcloud-dept</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springcloud-consumer-80</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!-- 引入自己定义的公共模块,可以使用Dept部门实体类 -->
<dependency>
<groupId>com.springcloud</groupId>
<artifactId>springcloud-common</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
3. application.yml
server:
port: 80
4. RestTemplateConfig配置类
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
5. Controller层
5.1 RestTemplate 描述
- RestTemplate提供了多种便捷的远程访问Http服务器的方法
- 是一种简单的快捷的访问Rest服务模版,Spring提供用于访问Rest服务客户端模版的工具集
- 官网:https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html
5.2 Controller层
@RestController
@RequestMapping("/consumer/dept")
public class ConsumerDeptController {
private static final String REST_URL_PREFIX = "http://localhost:8001";
@Resource
private RestTemplate restTemplate;
@RequestMapping("/list")
public List<Dept> listDept(){
//restTemplate.getForObject(REST请求的地址(提供者的地址),HTTP响应转换被转换是的对象)
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/list",List.class);
}
@RequestMapping("/get/{id}")
public Dept getDept(@PathVariable("id") Integer id){
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/get/"+id, Dept.class);
}
@RequestMapping("/add")
public boolean addDept(Dept dept){
//restTemplate.postForObject(REST请求的地址(提供者的地址),请求的参数,HTTP响应转换被转换是的对象)
return restTemplate.postForObject(REST_URL_PREFIX+"/dept/add", dept, Boolean.class);
}
}
6. 主启动类
@SpringBootApplication
public class DeptConsumer80Application {
public static void main(String[] args) {
SpringApplication.run(DeptConsumer80Application.class, args);
}
}
7. 测试
启动微服务提供者8001和微服务消费者80
http://localhost/consumer/dept/get/1