该系列(Spring Cloud学习案例)博客,是博主在学习周立先生《Spring Cloud与Docker微服务架构实战》一书时,将其中的案例部分,整理出来,并做一些细小的改动,添加一些自己的元素,记录下详细的步骤。
因为是案例分享,过多的理论知识不再赘述,只着重实战的过程。
第一个案例是关于一个简单的服务提供者和消费者,这个案例主要是让大家简历微服务的概念。
案例说明
用户通过客户端发起购票请求,首先发送给电影微服务,电影微服务需要知晓该用户的信息,又发送请求到用户微服务.关系如下:
案例分析
用户微服务:服务提供者,提供根据id查询用户信息.使用mybatis完成.
电影微服务:服务消费者,接受用户请求中的id参数,调用用户微服务提供的根据id查询用户信息的服务.使用restTemplate进行rest调用.
案例实现
1. 服务提供者
第一步:创建maven项目
第二步:编写pom.xml
该服务使用mybatis作为dao层框架,使用druid作为连接池,使用mysql数据库。
<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.cgg.springcloud</groupId> <artifactId>demo01-user-provider</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo01-user-provider</name> <description>服务提供者:用户微服务</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.10.RELEASE</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Edgware.SR3</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- springboot 整合 web开发 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- springboot 整合 druid --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.9</version> </dependency> <!-- springboot 整合 mysql --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- springboot 整合 mybatis --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> </dependencies> </project>
第三步:数据库准备
- 创建数据表t_user
CREATETABLE `t_user` ( `id` bigint(20) unsigned NOTNULL AUTO_INCREMENT, `username` varchar(32)NOTNULL, `name` varchar(32)NOTNULL, `age` int(3)NOTNULL, `balance` decimal(10,2)NOTNULL, PRIMARYKEY(`id`) ) ENGINE=InnoDBAUTO_INCREMENT=4DEFAULT CHARSET=utf8;
- 插入三条测试数据
INSERTINTO `t_user` VALUES(1,'damo','达摩',20,100.00); INSERTINTO `t_user` VALUES(2,'mulan','花木兰',22,100.00); INSERTINTO `t_user` VALUES(3,'daxiaojie','孙尚香',18,100.00);
第四步:配置数据源
在resources中创建application.yml文件。创建properties文件也行。
server: port: 9001 #================================== # 数据源配置 # ================================== spring: datasource: druid: url: jdbc:mysql:///springcloud username: root password: root
第五步:准备实体
package com.cgg.springcloud.demo1.pojo; publicclass User { private Long id; private String username; private String name; private Integer age; private Double balance; public Long getId() { returnid; } publicvoid setId(Long id) { this.id = id; } public String getUsername() { returnusername; } publicvoid setUsername(String username) { this.username = username; } public String getName() { returnname; } publicvoid setName(String name) { this.name = name; } public Integer getAge() { returnage; } publicvoid setAge(Integer age) { this.age = age; } public Double getBalance() { returnbalance; } publicvoid setBalance(Double balance) { this.balance = balance; } }
第六步:DAO层编写
- mapper接口
package com.cgg.springcloud.demo01.mapper; importcom.cgg.springcloud.demo01.pojo.User; publicinterface UserMapper { // 根据id查询用户信息 UserselectUserById(Long id); }
- UserMapper.xml文件
<?xml version="1.0"encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTDMapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.cgg.springcloud.demo01.mapper.UserMapper"> <!-- 根据id查询用户信息 --> <select id="selectUserById"parameterType="long" resultType="com.cgg.springcloud.demo01.pojo.User"> select* fromt_user whereid = #{id} </select> </mapper>
第七步:Service层编写
- 接口
package com.cgg.springcloud.demo01.service; importcom.cgg.springcloud.demo01.pojo.User; publicinterface UserService { // 根据id查询用户信息 UserselectUserById(Long id); }
- 实现类
packagecom.cgg.springcloud.demo01.service.impl; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.stereotype.Service; importorg.springframework.transaction.annotation.Transactional; importcom.cgg.springcloud.demo01.mapper.UserMapper; import com.cgg.springcloud.demo01.pojo.User; importcom.cgg.springcloud.demo01.service.UserService; @Service @Transactional publicclass UserServiceImpl implements UserService{ @Autowired private UserMapper userMapper; @Override public User selectUserById(Long id) { returnuserMapper.selectUserById(id); } }
第八步:Controller层编写
packagecom.cgg.springcloud.demo01.controller; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.web.bind.annotation.PathVariable; importorg.springframework.web.bind.annotation.RequestMapping; importorg.springframework.web.bind.annotation.RequestMethod; importorg.springframework.web.bind.annotation.RestController; importcom.cgg.springcloud.demo01.pojo.User; import com.cgg.springcloud.demo01.service.UserService; @RestController @RequestMapping("/user") publicclass UserController { @Autowired private UserService userService; @RequestMapping(value = "/{id}", method = RequestMethod.GET) public User selectUserById(@PathVariable Long id){ returnuserService.selectUserById(id); } }
第九步:启动类编写
注意需要进行mapper接口的自动扫描
package com.cgg.springcloud.demo01; importorg.mybatis.spring.annotation.MapperScan; importorg.springframework.boot.SpringApplication; importorg.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @MapperScan("com.cgg.springcloud.demo01.mapper") publicclass UserProviderApplication { publicstaticvoid main(String[] args) throws Exception { SpringApplication.run(UserProviderApplication.class, args); } }
第十步:测试
测试url:localhost:9001/user/1
2. 服务消费者
第一步:创建maven项目
第二步:编写pom.xml
因为电影微服务只是简单的使用restTemplate调用用户微服务的接口.所以只需添加springboot整合web开发的依赖即可.
<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.0http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.cgg.springcloud</groupId> <artifactId>demo01-movie-consumer</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo01-movie-consumer</name> <description>服务消费者:电影微服务</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.10.RELEASE</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Edgware.SR3</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- springboot 整合 web开发 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </project>
第三步:创建用户实体
消费者中的用户实体跟提供者的用户实体一致.在实际开发中,一般将pojo单独作为一个工程,打成jar,供其他项目依赖.
package com.cgg.springcloud.demo01.pojo; public class User { private Long id; private String username; private String name; private Integer age; private Double balance; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Double getBalance() { return balance; } public void setBalance(Double balance) { this.balance = balance; } }
第四步:编写启动类
因为启动类也是一个配置类. @SpringBootApplication是一个组合注解.在启动类中注册restTemplate的实例.
package com.cgg.springcloud.demo01; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @SpringBootApplication public class MovieConsumerApplication { // 在spring容器中注册restTemplate @Bean(name = "restTemplate") public RestTemplate getRestTemplate(){ return new RestTemplate(); } public static void main(String[] args) throws Exception { SpringApplication.run(MovieConsumerApplication.class, args); } }
第五步:编写controller
使用restTemplate调用提供者的接口.
package com.cgg.springcloud.demo01.controller; 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; import org.springframework.web.client.RestTemplate; import com.cgg.springcloud.demo01.pojo.User; @RestController @RequestMapping("/movie") public class MovieController { private static final String GET_USERINFO = "http://localhost:9001/user/"; @Autowired private RestTemplate restTemplate; @GetMapping("/user/{id}") public User getUserInfo(@PathVariable Long id){ return restTemplate.getForObject(GET_USERINFO + id, User.class); } }
第六步:配置application.yml
在resources下创建application.yml文件。配置项目启动端口.跟提供者区分开。
server: port: 9002
第七步:测试
测试url:http://localhost:9002/movie/user/1https://github.com/xiecheng310/springcloud.git
https://github.com/xiecheng310/springcloud.git