前言
本次我们将使用SpringCloud构建一个用户微服务案例,Consumer消费者(Client)通过REST调用Provider提供者(Server)提供的服务。
构建环境:SpringCloud Dalston.SR1
+Spring Boot 1.5.9.RELEASE
+Jdk 1.8
+Idea
+Maven 3.6
+MySQL
建立整体父工程(spring-cloud-examples)
新建父工程spring-cloud-examples
,packageing
是pom模式
File → New → Project → Maven
不用勾选任务任何选项,直接Next
输入GroupId和ArtifactId,然后Next → Finish
将如下pom文件内容复制到父工程(spring-cloud-examples
`)pom文件内
<?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.chaytech</groupId>
<artifactId>spring-cloud-examples</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<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>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.5.9.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.0.4</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.31</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</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>
因为是父工程,src
目录就不需要了,可以删除掉,最终效果如下
建立公共子模块(spring-cloud-model)
选中父工程(spring-cloud-examples
`)鼠标点击右键File → Module → Maven
不用勾选任务任何选项,直接Next → Finish
创建完成后,查看父工程pom文件的变化
可以看到多了上面所示的标签,modules
标签里的内容,代表父工程所拥有的模块,在创建子模块时,会自动创建此标签
接着修改spring-cloud-model
pom文件,增加Lombok
支持
<?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>spring-cloud-examples</artifactId>
<groupId>com.chaytech</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-model</artifactId>
<packaging>jar</packaging>
<!-- 当前Module需要用到的jar包,按自己需求添加,如果父类已经包含了,可以不用写版本号 -->
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
创建UserEntity
@NoArgsConstructor
@Data
public class UserEntity implements Serializable{
private int id;
private String username;
private String db_source; //来自那个数据库,因为微服务架构可以一个服务对应一个数据库,同一个信息被存储到不同数据库
public UserEntity(String username){
this.username = username;
}
}
最终工程展现
建立用户微服务提供者模块(spring-cloud-provider-user)
建立模块的步骤,参照公共子模块的建立,此处将不再演示
建立好后,修改pom文件
<?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>spring-cloud-examples</artifactId>
<groupId>com.chaytech</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-provider-user</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.chaytech</groupId>
<artifactId>spring-cloud-model</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</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-starter-tomcat</artifactId>
</dependency>
<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.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
</project>
创建application.yml
文件
server:
port: 8001
mybatis:
config-location: classpath:mybatis/mybatis-config.xml # mybatis配置文件所在路径
type-aliases-package: com.chaytech.model.* # 所有Entity别名类所在包
mapper-locations:
- classpath:mybatis/mapper/**/*.xml # mapper映射文件
spring:
application:
name: user-provider
datasource:
type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型
driver-class-name: org.gjt.mm.mysql.Driver # mysql驱动包
url: jdbc:mysql://127.0.0.1:3306/spring_cloud_db01 # 数据库名称
username: root
password: root
dbcp2:
min-idle: 5 # 数据库连接池的最小维持连接数
initial-size: 5 # 初始化连接数
max-total: 5 # 最大连接数
max-wait-millis: 200 # 等待连接获取的最大超时时间
eureka:
client: #客户端注册进eureka服务列表内
service-url:
defaultZone: http://localhost:7001/eureka
工程src/main/resources
目录下新建mybatis
文件夹后新建mybatis-config.xml
文件
<?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>
<settings>
<setting name="cacheEnabled" value="true"/><!-- 二级缓存开启 -->
</settings>
</configuration>
创建数据库、表、初始化数据,脚本如下
DROP DATABASE IF EXISTS spring_cloud_db01;
CREATE DATABASE spring_cloud_db01 CHARACTER SET UTF8;
USE spring_cloud_db01;
DROP TABLE IF EXISTS t_user
;
CREATE TABLE t_user
(
id
int(11) NOT NULL AUTO_INCREMENT,
username
varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
db_source
varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (id
) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
INSERT INTO t_user(username,db_source)
VALUES ( '小明', DATABASE());
INSERT INTO t_user(username,db_source)
VALUES ('小红', DATABASE());
创建UserDao
@Mapper
public interface UserDao {
public boolean insert(UserEntity user);
public UserEntity findById(Integer id);
public List<UserEntity> findAll();
}
工程src/main/resources
目录下新建mapper文件夹后创建UserMapper.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.chaytech.provider.user.dao.UserDao">
<select id="findById" resultType="com.chaytech.model.user.UserEntity" parameterType="java.lang.Integer">
select * from t_user where id = #{id};
</select>
<select id="findAll" resultType="com.chaytech.model.user.UserEntity">
select * from t_user;
</select>
<insert id="insert" parameterType="com.chaytech.model.user.UserEntity">
INSERT INTO t_user(username,db_source) VALUES(#{username},DATABASE());
</insert>
</mapper>
创建service
和controller
public interface IUserService {
public boolean createUser(UserEntity user);
public UserEntity getUser(Integer id);
public List<UserEntity> listUser();
}
public class UserServiceImpl implements IUserService {
@Autowired
private UserDao userDao;
@Override
public boolean createUser(UserEntity user) {
return userDao.insert(user);
}
@Override
public UserEntity getUser(Integer id) {
return userDao.findById(id);
}
@Override
public List<UserEntity> listUser() {
return userDao.findAll();
}
}
@RestController
public class UserController {
@Autowired
private IUserService userService;
@PostMapping("/user/createUser")
public boolean createUser(@RequestBody UserEntity user){
return userService.createUser(user);
}
@GetMapping("/user/getUser/{id}")
public UserEntity getUser(@PathVariable("id") Integer id){
return userService.getUser(id);
}
@GetMapping("/user/listUser")
public List<UserEntity> listUser(){
return userService.listUser();
}
}
启动类
@SpringBootApplication
public class UserProvider8001_Application {
public static void main(String[] args) {
SpringApplication.run(UserProvider8001_Application.class,args);
}
}
测试
http://127.0.0.1:8001/user/getUser/1
http://127.0.0.1:8001/user/listUser
最终工程展现
建立用户微服务消费者模块(spring-cloud-consumer-user
建立模块的步骤,参照公共子模块的建立,此处将不再演示
建立好后,修改pom文件
<?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>spring-cloud-examples</artifactId>
<groupId>com.chaytech</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-consumer-user</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.chaytech</groupId>
<artifactId>spring-cloud-model</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 修改后立即生效,热部署 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
</project>
创建application.yml
文件
server:
port: 80
当微服务消费者去调用微服务提供者的时候需要用到一个组件RestTemplate
:RestTemplate
提供了多种便捷访问远程Http服务的方法, 是一种简单便捷的访问restful服务模板类,是Spring提供的用于访问Rest服务的客户端模板工具集
使用RestTemplate
访问restful接口非常的简单粗暴无脑。
(url, requestMap, ResponseBean.class)这三个参数分别代表
REST请求地址、请求参数、HTTP响应转换被转换成的对象类
首先创建RestTemplateConfig
,将RestTemplate
放入到spring容器中
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
消费者调用微服务提供者提供的服务
@RestController
public class UserController {
private static final String REST_URL_PREFIX = "http://127.0.0.1:8001";
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "/consumer/user/add")
public boolean add(UserEntity user) {
return restTemplate.postForObject(REST_URL_PREFIX + "/user/createUser", user, Boolean.class);
}
@RequestMapping(value = "/consumer/user/getUser/{id}")
public UserEntity get(@PathVariable("id") Integer id) {
return restTemplate.getForObject(REST_URL_PREFIX + "/user/getUser/" + id, UserEntity.class);
}
@SuppressWarnings("unchecked")
@RequestMapping(value = "/consumer/user/listUser")
public List<UserEntity> list() {
return restTemplate.getForObject(REST_URL_PREFIX + "/user/listUser", List.class);
}
}
启动类
@SpringBootApplication
public class UserConsumer80_Application {
public static void main(String[] args) {
SpringApplication.run(UserConsumer80_Application.class,args);
}
}
测试
此处测试的话,因为消费者最终是调用提供者的服务,所以要将spring-cloud-provider-user
和spring-cloud-consumer-user
两个微服务同时启动起来
http://127.0.0.1:80/consumer/user/getUser/1
我在服务提供者getUser
代码处打个断点,可以看到,请求消费者的getUser
服务http://127.0.0.1:80/consumer/user/getUser/1,最终会转发到服务提供者http://127.0.0.1:8001/user/getUser/1
http://127.0.0.1:80/consumer/user/listUser
ok,SpringCloud微服务基础环境已成功搭建!