1. SpringBoot 和 SpringCloud 版本关系
- Spring 官网提供的查询版本对应关系的接口 :https://start.spring.io/actuator/info
在实际开发过程中,我们需要更详细的版本对应:
2. 环境搭建
2.1. 父项目
-
创建一个 Maven 项目作为父项目
-
删除父项目中的 src 目录(用不上)
-
修改父项目的 POM 文件,导入依赖
<!--修改打包方式为 pom--> <packaging>pom</packaging> <properties> <!--把依赖的版本号提出来--> <junit.version>4.12</junit.version> <lombok.version>1.18.12</lombok.version> </properties> <!--使用依赖管理--> <dependencyManagement> <dependencies> <!--SpringCloud 的依赖--> <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR4</version> <type>pom</type> <scope>import</scope> </dependency> <!--Spring Boot 的依赖--> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-dependencies --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.2.0.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> <!--数据库连接--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.11</version> </dependency> <!--druid数据源--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.21</version> </dependency> <!--SpringBoot 启动器--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.2.0.RELEASE</version> </dependency> <!--mybatis 启动器--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.3</version> </dependency> <!--log4j--> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.2.3</version> </dependency> <!--Junit--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <!--这里引用--> <version>${junit.version}</version> <scope>test</scope> </dependency> <!--lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </dependency> </dependencies> </dependencyManagement>
2.2. API 服务 —— POJO
-
再新建一个 Maven 模块:springcloud-01-API
-
修改 springcloud-01-API 的 POM 引入父项目中定义的依赖
<!--当前模块需要用的依赖--> <dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
-
创建一个数据库 spring_cloud_01
部门表create table dept ( deptno bigint auto_increment, dname varchar(60) null, `db_source` varchar(60) null comment '数据库的标识', constraint dept_pk primary key (deptno) ) comment '部门表';
# 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()); insert into dept(dname, `db_source`) values ('运维部', database());
-
建立对应的实体类
使用微服务的时候,实体类必须实现序列化
需要把 实体类 映射到 数据表@Data @NoArgsConstructor @Accessors(chain = true)// 设置支持链式写法 public class Dept implements Serializable { private Long deptno; private String dname; private String db_source; /** * 构造器 */ public Dept(String dname) { this.dname = dname; } }
2.3. 服务提供者
-
新建一个 SpringBoot 模块 :springcloud-02-provider-dept-8081
因为是微服务,服务较多,在包名上标注上端口号
-
配置 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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.demo</groupId> <version>0.0.1-SNAPSHOT</version> <parent> <artifactId>Demo_SpringCloud</artifactId> <groupId>org.demo</groupId> <version>1.0-SNAPSHOT</version> </parent> <artifactId>springcloud-02-provider-dept-8081</artifactId> <properties> <java.version>1.8</java.version> </properties> <dependencies> <!--需要得到实体类,所以需要配置 API 模块--> <dependency> <groupId>org.demo</groupId> <artifactId>SpringCloud-01-API-8080</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </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</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test</artifactId> </dependency> <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> <!--jetty,类似 Tomcat--> <!--<dependency>--> <!-- <groupId>org.springframework.boot</groupId>--> <!-- <artifactId>spring-boot-starter-jetty</artifactId>--> <!--</dependency>--> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
-
新建一个application.yml 文件,并编写
server: port: 8081 mybatis: type-aliases-package: com.demo.pojo mapper-locations: classpath:mybatis/mapper/*.xml config-location: classpath:mybatis/mybatis-config.xml spring: application: name: SpringCloud-02-provider datasource: username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/spring_cloud_01?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8 type: com.alibaba.druid.pool.DruidDataSource
-
新建 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>
-
编写 Mapper
mapper 接口@Mapper @Repository public interface DeptMapper { /**增加 * @param dept * @return */ public boolean addDept(Dept dept); /** 按照 id 查询 * @param id * @return */ public Dept queryDeptById(Long id); /** 查询所有 * @return */ public List<Dept> queryDepts(); }
mapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.demo.mapper.DeptMapper"> <insert id="addDept" parameterType="Dept"> insert into dept(dname, `db_source`) values (#{dname}, database()) </insert> <select id="queryDeptById" parameterType="Long" resultType="Dept"> select * from dept where deptno=#{deptno} </select> <select id="queryDepts" resultType="Dept"> select * from dept </select> </mapper>
-
编写 Service
service 接口public interface DeptService { /**增加 * @param dept * @return */ public boolean addDept(Dept dept); /** 按照 id 查询 * @param id * @return */ public Dept queryDeptById(Long id); /** 查询所有 * @return */ public List<Dept> queryDepts(); }
serviceimpl
@Service public class DeptServiceImpl implements DeptService { @Autowired DeptMapper deptMapper; @Override public boolean addDept(Dept dept) { return deptMapper.addDept(dept); } @Override public Dept queryDeptById(Long id) { return deptMapper.queryDeptById(id); } @Override public List<Dept> queryDepts() { return deptMapper.queryDepts(); } }
-
编写 Controller
@RestController public class DeptController { @Autowired private DeptService deptService; @PostMapping("/addDept") public Boolean addDept(Dept dept) { return deptService.addDept(dept); } @GetMapping("/queryDeptById/{id}") public Dept queryDeptById(@PathVariable("id") Long id){ return deptService.queryDeptById(id); } @GetMapping("/queryDepts") public List<Dept> queryDepts() { return deptService.queryDepts(); } }
-
目录结构
-
启动项目测试
页面成功打印对应数据,成功
2.4. 服务消费者
-
新建一个 SpringBoot 模块 :springcloud-03-consumer-dept-8082
-
编写 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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.demo</groupId> <version>0.0.1-SNAPSHOT</version> <parent> <artifactId>Demo_SpringCloud</artifactId> <groupId>org.demo</groupId> <version>1.0-SNAPSHOT</version> </parent> <artifactId>springcloud-03-consumer-dept-8082</artifactId> <properties> <java.version>1.8</java.version> </properties> <dependencies> <!--实体类--> <dependency> <groupId>org.demo</groupId> <artifactId>SpringCloud-01-API-8080</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!--web 启动--> <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> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
-
编写 application.yml
server: port: 8082
-
编写一个 bean 的配置类 : BeanConfig
@Configuration public class BeanConfig { /** * 把 RestTemplate 注册到 Spring 中 * 需要什么就返回什么 * 这里需要注册 RestTemplate 那么就把它返回 * @return */ @Bean public RestTemplate getRestTemplate(){ return new RestTemplate(); } }
-
控制层 :DeptConsumerController
@RestController public class DeptConsumerController { // 消费者没有 Service 层,那就需要使用 Rest 去请求 // 那么肯定有一个 RestTemplate 模板,这里面肯定有很多供我们调用的方法 // 既然这样就需要把它注册到 Spring 中 @Autowired private RestTemplate restTemplate; /** * 提供者 URL 的前缀 */ private static final String REST_URL_PREFIX = "http://localhost:8081"; /** * 需要去提供者那里获取服务 * @param id * @return */ @RequestMapping("/consumer/getDeptById/{id}") public Dept getDeptById(@PathVariable("id")Long id){ // 去提供者那里,通过 Get 请求获取一个对象 // getForObject 的参数:提供者地址;【请求所需的参数】 ; 返回值对象的类 // 请求需要传递的参数; // 1. 通过URL拼接; // 2. 使用 Map 传参 ; // 3. 直接传递参数对象(就像下面的 Add 方法) return restTemplate.getForObject(REST_URL_PREFIX+"/queryDeptById"+id,Dept.class); } @RequestMapping("/consumer/getDepts") public List<Dept> getDepts(){ return restTemplate.getForObject(REST_URL_PREFIX+"/queryDepts",List.class); } @RequestMapping("/consumer/addDept") public Boolean addDept(Dept dept){ return restTemplate.postForObject(REST_URL_PREFIX+"/addDept",dept,Boolean.class); } }
-
目录结构
-
启动项目测试
先启动 提供者 的服务
访问成功