Spring Cloud 环境初搭建:多模块项目管理

Spring Boot 和 Spring Cloud 版本选择

Spring Cloud 官网:https://spring.io/projects/spring-cloud#learn
Spring Boot 官网:https://spring.io/projects/spring-boot#learn

Spring Boot 官方强烈建议你升级到2.X以上版本

Spring Boot 和 Spring Cloud 版本对应查看方法

访问网站:https://start.spring.io/actuator/info

查看JSON串返回结果
在这里插入图片描述
在线格式化JSON

网址:https://www.json.cn/

列出了SpringCloud 和 SpringBoot 版本对应关系。
在这里插入图片描述

父工程Project空间创建

在这里插入图片描述

父工程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.kernel.springcloud</groupId>
    <artifactId>cloud-kernel</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging> <!-- 这里添加pom,注意不是jar或war -->

    <!-- 统一管理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>
        <spring.boot.version>2.3.2.RELEASE</spring.boot.version>
        <spring.cloud.version>Hoxton.SR7</spring.cloud.version>
        <lombok.version>1.16.18</lombok.version>
        <mysql-connector-java.version>8.0.23</mysql-connector-java.version>
        <druid.version>1.1.14</druid.version>
        <swagger.version>2.9.2</swagger.version>
        <mybatis.start.version>1.3.0</mybatis.start.version>
        <hutool.version>4.1.19</hutool.version>
    </properties>

    <!-- 依赖管理 子模块继承之后,提供作用:锁定版本 + 子module 不用写groupId和version -->
    <dependencyManagement>
        <dependencies>
            <!--spring boot 2.3.12.RELEASE-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring.boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!--spring cloud Hoxton.SR12-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring.cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql-connector-java.version}</version>
            </dependency>

            <!--阿里数据库连接池 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>${druid.version}</version>
            </dependency>

            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.start.version}</version>
            </dependency>

            <!-- lombok -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
                <optional>true</optional>
            </dependency>

            <!-- swagger -->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
                <version>${swagger.version}</version>
            </dependency>

            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
                <version>${swagger.version}</version>
            </dependency>

            <!-- 工具类大全糊涂 -->
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>${hutool.version}</version>
            </dependency>

        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

DependencyManagement 和 Dependencies

Maven使用DependencyManagement元素来提供了一种管理依赖版本号的方式。

通常会在一个组织或者项目的最顶层的父POM中看到DependencyManagement元素。

使用pom.xml中的DependencyManagement元素能让所有在子项目中引用个依赖而不用显式的列出版本量。

Maven会沿着父子层次向上走,直到找到一个拥有DependencyManagement元素的项目,然后它就会使用这个DependencyManagement元素中指定的版本号。

这样做的好处就是:如果有多个子项目都引用同一样依赖,则可以避免在每个使用的子项目里都声明一个版本号,这样当想升级或切换到另一个版本时,只需要在顶层父容器里更新,而不需要一个一个子项目的修改;另外如果某个子项目需要另外的一个版本,只需要声明version就可。

DependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。

如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom。

如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。

公共模块创建

cloud-api-common

公共模块:用来存放工具类等各模块通用的代码。
在这里插入图片描述

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>cloud-kernel</artifactId>
        <groupId>com.kernel.springcloud</groupId>
        <version>1.0.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>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
        </dependency>

        <!-- swagger -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
        </dependency>
    </dependencies>

</project>

如接口统一返回封装

package com.kernel.web;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;


@ApiModel(description = "接口返回数据")
@Data
public class RestResult<T> {
    @ApiModelProperty(value = "返回状态码")
    private int code;

    @ApiModelProperty(value = "描述信息")
    private String msg;

    @ApiModelProperty(value = "返回数据")
    private T data;


    // 成功,不返回具体数据
    public static <T> RestResult<T> successNoData(ResultCode code) {
        RestResult<T> result = new RestResult<T>();
        result.setCode(code.getCode());
        result.setMsg(code.getMsg());
        return result;
    }

    // 成功,返回数据
    public static <T> RestResult<T> success(T t, ResultCode code) {
        RestResult<T> result = new RestResult<T>();
        result.setCode(code.getCode());
        result.setMsg(code.getMsg());
        result.setData(t);
        return result;
    }

    // 失败,返回失败信息
    public static <T> RestResult<T> fail(ResultCode code) {
        RestResult<T> result = new RestResult<T>();
        result.setCode(code.getCode());
        result.setMsg(code.getMsg());
        return result;
    }

}

public enum ResultCode {

    /* 成功状态码 */
    SUCCESS(0, "Success"), //成功
    
    DATA_ACCESS_ERROR(50004, " Data_access_error"), //数据库访问错误

    /* 参数错误:10001-19999 */
    PARAM_IS_INVALID(10001, "Param_invalid"), // 参数无效
    PARAM_IS_BLANK(10002, "Param_null"), // 参数为空
    PARAM_NOT_COMPLETE(10003, "Param_missing"); //参数缺失

    private Integer code;

    private String msg;

    ResultCode(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public Integer getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}

服务提供者模块创建

创建微服务模块套路:

  1. 新建Module
  2. 修改pom文件
  3. 编写配置文件yml
  4. 编写主启动类
  5. 编写业务代码

创建cloud-provider-8001微服务提供者模块:

1.新建名为 cloud-provider-8001 的Module的Maven工程

父pom变化,多了modules 元素

<modules>
   <module>cloud-api-common</module>
   <module>cloud-provider-8001</module>
</modules>

2.修改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>cloud-kernel</artifactId>
        <groupId>com.kernel.springcloud</groupId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-provider-8001</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>

        <!-- 我们自己的公共模块 -->
        <dependency>
            <groupId>com.kernel.springcloud</groupId>
            <artifactId>cloud-api-common</artifactId>
            <version>${project.version}</version>
        </dependency>

        <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>
        </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>
    </dependencies>

</project>

3.编写配置文件yml

server:
  port: 8001

spring:
  application:
    name: cloud-provider-service                            # 服务名称
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource            # 当前数据源操作类型
    driver-class-name: com.mysql.jdbc.Driver                # mysql驱动包
    url: jdbc:mysql://localhost:3306/idata_baiir?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
    username: ******
    password: ******

mybatis:
  mapperLocations: classpath:mapper/*.xml
  type-aliases-package: com.kernel.entity    # 所有Entity别名类所在包

4.主启动类

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

/**
 * @ClassName ProviderApplication
 * @author: shouanzh
 * @Description ProviderApplication
 * @date 2022/4/16 17:18
 */

@SpringBootApplication
public class ProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class,args);
    }
}

5. 编写业务代码

简单的三层架构 controller -> service -> DAO

一个简单数据库表

user_test表:id、name、age 三个字段

在这里插入图片描述
entity

UserTest实体类(实体类放在了公共模块下)

/**
 * UserTest PO实体类
 */
@Data
@ApiModel(description = "用户信息")
public class UserTest {

    @ApiModelProperty(name = "id", value = "id")
    private Long id;

    @ApiModelProperty(name = "name", value = "名字")
    private String name;

    @ApiModelProperty(name = "age", value = "年龄")
    private Integer age;
}

DAO

UserTestMapper.java

/**
 * UserTest Dao层接口
 */
@Mapper
public interface UserTestMapper {

    /**
     * 插入对象
     */
    int insert(UserTest userTest);

    /**
     * 更新对象
     */
    int update(UserTest userTest);

    /**
     * 删除对象
     */
    int delete(Long id);


    /**
     * 获取单个对象
     */
    UserTest selectOne(Long id);

    /**
     * 获取列表
     */
    List<UserTest> selectList(UserTest userTest);

}

UserTest.xml 路径:resources/mapper/UserTest.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.da.springcloud.mapper.UserTestMapper">

    <resultMap id="UserTest" type="com.kernel.entity.po.UserTest">
        <result property="id" column="ID"/>
        <result property="name" column="NAME"/>
        <result property="age" column="AGE"/>
    </resultMap>

    <insert id="insert" parameterType="com.kernel.entity.po.UserTest" useGeneratedKeys="true"
            keyProperty="id">
        INSERT INTO USER_TEST (
        <trim prefixOverrides=",">
            <if test="id != null">,ID</if>
            <if test="name != null">,NAME</if>
            <if test="age != null">,AGE</if>
        </trim>
        ) VALUES (
        <trim prefixOverrides=",">
            <if test="id != null">,#{id}</if>
            <if test="name != null">,#{name}</if>
            <if test="age != null">,#{age}</if>
        </trim>
        )
    </insert>


    <update id="update" parameterType="com.kernel.entity.po.UserTest">
        UPDATE USER_TEST
        <set>
            <if test="name != null">NAME = #{name},</if>
            <if test="age != null">AGE = #{age},</if>
        </set>
        WHERE ID = #{id}
    </update>

    <select id="selectOne" parameterType="java.lang.Long" resultMap="UserTest">
        SELECT ID,
               NAME,
               AGE
        FROM USER_TEST
        WHERE ID = #{id} LIMIT 1
    </select>

    <select id="selectList" parameterType="com.kernel.entity.po.UserTest" resultMap="UserTest">
        SELECT
        ID,
        NAME,
        AGE
        FROM USER_TEST
        <where>
            <if test="id != null">AND ID = #{id}</if>
            <if test="name != null">AND NAME = #{name}</if>
            <if test="age != null">AND AGE = #{age}</if>
        </where>
    </select>

    <delete id="delete" parameterType="java.lang.Long">
        DELETE
        FROM USER_TEST
        WHERE ID = #{id}
    </delete>

</mapper>

Service:

/**
 * UserTest Service层接口
 */
public interface IUserTestService {


    /**
     * 删除
     * @param id
     * @return
     */
    int delete(Long id);// 删除


    /**
     * 新增
     * @param userTest
     * @return
     */
    int insert(UserTest userTest);

    /**
     * 更新
     * @param userTest
     * @return
     */
    int update(UserTest userTest);

    /**
     * 根据主键查找
     * @param id
     * @return
     */
    UserTest selectOne(Long id);

    /**
     * 根据条件查询
     * @param userTest
     * @return
     */
    List<UserTest> selectList(UserTest userTest);

}
/**
 * UserTest Service层实现
 */
@Service
public class UserTestServiceImpl implements IUserTestService {

    @Autowired
    private UserTestMapper userTestMapper;

    /**
     * 删除
     *
     * @param id
     * @return
     */
    @Override
    public int delete(Long id) {
        return userTestMapper.delete(id);
    }

    /**
     * 新增
     *
     * @param userTest
     * @return
     */
    @Override
    public int insert(UserTest userTest) {
        return userTestMapper.insert(userTest);
    }

    /**
     * 更新
     *
     * @param userTest
     * @return
     */
    @Override
    public int update(UserTest userTest) {
        return userTestMapper.update(userTest);
    }

    /**
     * 根据主键查找
     *
     * @param id
     * @return
     */
    @Override
    public UserTest selectOne(Long id) {
        return userTestMapper.selectOne(id);
    }

    /**
     * 根据条件查询
     *
     * @param userTest
     * @return
     */
    @Override
    public List<UserTest> selectList(UserTest userTest) {
        return userTestMapper.selectList(userTest);
    }
}

controller

@Api(tags = "用户管理接口")
@RestController
@Slf4j
@RequestMapping("/user")
public class UserController {

    @Autowired
    private IUserTestService userTestService;

    @ApiOperation(value="查询用户")
    @PostMapping(value = "/search/v1")
    public RestResult<List<UserTest>> search(@RequestBody UserTest userTest) {

        try {

            List<UserTest> userTests = userTestService.selectList(userTest);

            return RestResult.success(userTests, ResultCode.SUCCESS);
        } catch (Exception e) {
            return RestResult.fail(ResultCode.DATA_ACCESS_ERROR);
        }

    }


    @ApiOperation(value="删除用户")
    @PostMapping(value = "/delete/v1")
    @ApiImplicitParam(name = "id", value = "用户ID", required = true)
    public RestResult delete(Long id) {


        try {

            userTestService.delete(id);

            return RestResult.successNoData(ResultCode.SUCCESS);

        } catch (Exception e) {

            return RestResult.fail(ResultCode.DATA_ACCESS_ERROR);

        }

    }
}

整合Swagger配置

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .pathMapping("/")
                .select()
                .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
                .paths(PathSelectors.any())
                .build()
                .apiInfo(apiInfo())
                .securitySchemes(securitySchemes());
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("spring cloud 接口测试文档")
                .description("spring cloud 接口测试文档")
                .version("3.0")
                .contact(new Contact("shouanzh","","1432680552@qq.com"))
                .license("")
                .licenseUrl("")
                .build();
    }

    /**
     * SecurityScheme 子类 BasicAuth OAuth ApiKey
     *
     * @return
     */
    private List<SecurityScheme> securitySchemes() {
        List<SecurityScheme> list = new ArrayList<>();
        // basicAuth SwaggerBootstrapUI支持的不好,使用swagger原生UI
        // list.add(new BasicAuth("basicAuth"));
        // name 为参数名  keyname是页面传值显示的 keyname, name在swagger鉴权中使用
        list.add(new ApiKey("authorization", "authorization",
                "header"));
        return list;
    }
}

测试

swagger 访问地址:http://localhost:8001/swagger-ui.html

在这里插入图片描述
在这里插入图片描述
总体结构

在这里插入图片描述
至此 服务提供者模块搭建完毕

消费者模块创建

1.新建Module

创建名为cloud-consumer-80的maven工程。

2.修改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>cloud-kernel</artifactId>
        <groupId>com.kernel.springcloud</groupId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-consumer-80</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>

        <!-- 我们自己的公共模块 -->
        <dependency>
            <groupId>com.kernel.springcloud</groupId>
            <artifactId>cloud-api-common</artifactId>
            <version>${project.version}</version>
        </dependency>

        <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>

    </dependencies>

</project>

3.编写yml配置文件

application.yml

server:
  port: 80
  
spring:
  application:
    name: cloud-consumer-service

4.主启动类

@SpringBootApplication
public class ConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class,args);
    }
    
}

使用RestTemplate调用服务提供模块

RestTemplate配置

@Configuration
public class ApplicationContextConfig {

    @Bean
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

controller

@RestController
@Api(tags = "消费端")
public class ConsumerController {

    public static final String PROVIDER_URL = "http://localhost:8001";

    @Autowired
    private RestTemplate restTemplate;


    @ApiOperation(value="查询用户")
    @PostMapping(value = "/search/v1")
    public RestResult search(@RequestBody UserTest userTest) {

        try {

            return restTemplate.postForObject(PROVIDER_URL + "/user/search/v1", userTest, RestResult.class);

        } catch (Exception e) {
            return RestResult.fail(ResultCode.DATA_ACCESS_ERROR);
        }

    }
}

总体结构

在这里插入图片描述

测试

启动俩个服务
在这里插入图片描述
消费端swagger地址:http://localhost/swagger-ui.html

在这里插入图片描述

到此 服务提供者 和 服务消费者 搭建完毕,并使用RestTemplate调用服务提供者。接下来将进行spring cloud 组件的融合。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值