微服务基础环境搭建--和创建公用模块

news2024/10/5 15:31:20

目录

微服务基础环境搭建

创建父工程,用于聚合其它微服务模块

创建父项目, 作为聚合其它微服务模块

项目设置​编辑 ​编辑

删除src, 保留一个纯净环境​编辑 

1. 配置父工程pom.xml, 作为聚合其它模块

2、修改e-commerce-center\pom.xml,删除不需要的配置节点

注意事项和细节

● 作用范围一览图​编辑

创建会员中心微服务模块-service provider

需求说明/图解

 思路分析/图解

创建member-service-provider-10000 微服务模块[提供会员服务] 

父工程的pom.xml-会做相应变化,管理member-service-provider-10000 微服务子模块 ​编辑

 修改member-service-provider-10000 的pom.xml , 加入相关依赖 

刷新maven , 注意看引入的jar 的版本

创建resources/application.yml 

 创建主启动类MemberApplication

创建数据库/表

业务实现entity

创建entity/Result.java

创建接口:/dao/MemberDao.java 

 创建resources/mapper/MemberMapper.xml

完成测试 

创建接口:service/MemberService.java

创建/impl/MemberServiceImpl.java

创建springcloud/controller/MemberController.java

注意事项和细节

创建使用会员微服务模块-service consumer 

示意图

浏览器: http://localhost/member/consumer/get/1

-测试添加会员: http://localhost/member/consumer/save

 创建Moduel(member-service-consumer-80) & 完成配置

 修改member-service-consumer-80 的pom.xml , 加入相关依赖

创建resources/application.yml

创建主启动类MemberConsumerApplication.java

 业务实现entity

创建entity/Result.java

注入RestTemplate

基本介绍

● 官网地址

创建配置类: config/CustomizationBean.java

修改Controller

完成测试

注意事项和使用细节

添加会员数据库中为null 的解决方案

​编辑

开启Run DashBoard

​编辑

 ​编辑

创建共用模块-供其它模块使用 

思路分析/图解

创建e_commerce_center-common-api

修改e_commerce_center-common-api 的pom.xml 

抽取共用API/类

创建Member 类 

创建entity/Result.java

使用Maven 打包成jar

工程重构

完成测试


微服务基础环境搭建

 

创建父工程,用于聚合其它微服务模块

创建父项目, 作为聚合其它微服务模块

1、说明:我们先创建一个父项目, 该父项目会去管理多个微服务模块(module), 如图 

2、创建父项目步骤-- 灵活配置方式  

项目设置 

 

删除src, 保留一个纯净环境 

1. 配置父工程pom.xml, 作为聚合其它模块

    <!--列出了父项目/父工程聚合管理的子模块/子项目-->
    <modules>
        <module>member-service-provider-10000</module>
        <module>member-service-consumer-80</module>
        <module>e_commerce_center-common-api</module>
        <module>e-commerce-eureka-server-9001</module>
        <module>e-commerce-eureka-server-9002</module>
        <module>member-service-provider-10002</module>
        <module>e-commerce-consumer-openfeign-80</module>
        <module>e-commerce-gateway-20000</module>
        <module>member-service-nacos-provider-10004</module>
        <module>member-service-nacos-provider-10006</module>
        <module>member-service-nacos-consumer-80</module>
        <module>e-commerce-nacos-config-client5000</module>
        <module>seata_storage_micro_service-10010</module>
        <module>seata_account_micro_service-10012</module>
        <module>seata-order-micro-service-10008</module>
    </modules>
    <!-- 表明是一个父工程,聚合管理其他模块 -->
    <packaging>pom</packaging>

    <name>e-commerce-center</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>

    <!--提醒: 版本和保持一致: 否则容易出现版本兼容问题, 先跟着走通一套配置-->
    <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 , 防止安全漏洞
        -->
        <log4j.version>2.17.2</log4j.version>
        <lombok.version>1.18.20</lombok.version>
        <mysql.version>5.1.47</mysql.version>
        <druid.version>1.1.17</druid.version>
        <mybatis.spring.boot.version>2.2.0</mybatis.spring.boot.version>
    </properties>

    <!--说明: dependencyManagement 配置各个依赖和版本: 后面如果有需要,还要增加-->
    <dependencyManagement>
        <dependencies>
            <!--配置spring-boot-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.2.2.RELEASE</version>
                <!--
                    解读:
                    1. type: pom  和 scope import 配合使用
                    2. 表示 父项目的子模块, 在引入springboot相关依赖时 锁定版本为2.2.2.RELEASE
                    3. 通过 pom + import 解决maven单继承机制
                 -->
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--配置spring-cloud-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--配置cloud-alibaba-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.1.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

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

            <!--配置druid数据源-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>${druid.version}</version>
            </dependency>

            <!--配置springboot整合mybatis starter-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.spring.boot.version}</version>
            </dependency>

            <!--配置log4j ,使用的最新高版本-->
            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j.version}</version>
            </dependency>

            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
            </dependency>

            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

2、修改e-commerce-center\pom.xml,删除不需要的配置节点

<!--删除build 和reporting 节点-->

<build>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be
moved to parent pom) -->
        <plugins>
            <plugin>
                <artifactId>maven-clean-plugin</artifactId>
                <version>3.1.0</version>
            </plugin>
            <plugin>
                <artifactId>maven-site-plugin</artifactId>
                <version>3.7.1</version>
            </plugin>
            <plugin>
                <artifactId>maven-project-info-reports-plugin</artifactId>
                <version>3.0.0</version>
            </plugin>
        </plugins>
    </pluginManagement>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-site-plugin</artifactId>
            <configuration>
                <locales>en,fr</locales>
            </configuration>
        </plugin>
    </plugins>
</build>
<reporting>
<plugins>
    <plugin>
        <artifactId>maven-project-info-reports-plugin</artifactId>
    </plugin>
</plugins>
</reporting>

注意事项和细节

Maven 的dependencyManagement 说明
dependencyManagement 细节说明

1、Maven 使用dependencyManagement 元素来提供了一种管理依赖版本号的方式。通常在项目packaging 为POM, 中使用dependencvManadement 元素。

2、使用pom.xml 中的dependencyManagement 元素能让所有在子项目中引用一个依赖, Maven 会沿着父子层次向上走, 直到找到一个拥有dependencyManagement 元素的项目, 然后它就会使用这个dependencyManagement 元素中指定的版本号。

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

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

 

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

● 作用范围一览图

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

 

创建会员中心微服务模块-service provider

需求说明/图解

1、通过浏览器可以获取会员信息(通过会员中心微服务模块)2. 使用Postman 测试查询 

 3. 通过Postman 测试加

 思路分析/图解

1、创建Moduel & 完成配置
2、创建数据库/表
3、创建entity-dao/Mapper.xml-service-controller
4、完成测试

创建member-service-provider-10000 微服务模块[提供会员服务] 

 

 

父工程的pom.xml-会做相应变化,管理member-service-provider-10000 微服务子模块 

 

 修改member-service-provider-10000 的pom.xml , 加入相关依赖 

    <!--该项目继承成父项目的groupId是 com.wyxedu.springcloud-->
    <!--因此这里就不需要在指定groupId-->
    <artifactId>member-service-provider-10000</artifactId>

    <!--引入相关的依赖-->
    <dependencies>
        <!--引入sleuth + zipkin 依赖 说明 1. 使用的是版本仲裁 2.starter-zipkin包含了sleuth  -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>
        <!--引入eureka-client 场景启动器starter: 使用版本仲裁-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!--引入web-starter 说明我们使用版本仲裁(从父项目继承了版本)
        -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--说明:starter-actuator 是springboot程序的监控系统, 可以实现系统的健康检测
        可以通过http://localhost:10000/actuator 看到相关的连接,和信息
        -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <!--引入mybatis-starter 整合到springboot-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>

        <!--引入druid-starter-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <!--这里需要我们指定版本, 因为父项目没有-->
            <version>1.1.17</version>
        </dependency>

        <!--引入mysql依赖,使用版本仲裁-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!--spring-boot-start-jdbc引入-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

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

        <!--引入test-starter-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>

刷新maven , 注意看引入的jar 的版本

创建resources/application.yml 

server:
  port: 10000

spring:
  application:
    name: member-service-provider #配置应用的名称
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    url: jdbc:mysql://localhost:3306/e_commerce_center_db?useSSL=true&useUnicode=true&characterEncoding=UTF-8
    username: root
    password: 自己的密码
#配置mybatis
mybatis:
  mapper-locations: classpath:mapper/*.xml #指定mapper.xml文件位置
  type-aliases-package: com.wyxedu.springcloud.entity # 实例类所在的包,这样通过类名就可以引用

 创建主启动类MemberApplication

//注意加上@SpringBootApplication
@SpringBootApplication
public class MemberApplication {
    public static void main(String[] args) {
        SpringApplication.run(MemberApplication.class, args);
    }
}

创建数据库/表

CREATE DATABASE e_commerce_center_db
USE e_commerce_center_db
CREATE TABLE member
(
id BIGINT NOT NULL AUTO_INCREMENT COMMENT 'id',
NAME VARCHAR(64) COMMENT '用户名',
pwd CHAR(32) COMMENT '密码',
mobile VARCHAR(20) COMMENT '手机号码',
email VARCHAR(64) COMMENT '邮箱',
gender TINYINT COMMENT '性别',
PRIMARY KEY (id)
);
INSERT INTO member VALUES
(NULL, 'smith', MD5('123'), '123456789000', 'smith@sohu.com', 1);
SELECT * FROM member

业务实现
entity

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Member{
    private Long id;
    private String name;
    private String pwd;
    private String mobile;
    private String email;
    private Integer gender;
}

创建entity/Result.java


/**
 * Result: 返回结果对象: 以json格式返回
 * 我我的springboot + vue项目的博客中有介绍过
 * * 说明
 * * 1. Result<T> 自定义泛型类
 * * 2. Result<T> 对象就是后端返回给前端的数据,是以json格式返回
 */
public class Result<T> {
    private String code; //状态码
    private String msg; //对状态说明
    private T data; // 返回时,携带的数据, 为了扩展性好,使用泛型

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }


    //无参构造器
    public Result() {

    }

    //带参构造器-指定返回的data
    public Result(T data) {
        this.data = data;
    }

    //编写方法-返回需要的Result对象-表示成功的Result
    public static Result success() {
        Result result = new Result<>();
        result.setCode("200");
        result.setMsg("success");
        return result;
    }

    //编写方法-返回需要的Result对象-表示成功的Result,同时可以携带数据
    //如果需要在static方法使用泛型,需要在 static <T>
    public static <T> Result<T> success(T data) {
        Result<T> result = new Result<>(data);
        result.setCode("200");
        result.setMsg("success");
        return result;
    }

    //编写方法-返回需要的Result对象-表示成功的Result,同时可以携带数据和指定msg
    //如果需要在static方法使用泛型,需要在 static <T>
    public static <T> Result<T> success(String msg, T data) {
        Result<T> result = new Result<>(data);
        result.setCode("200");
        result.setMsg(msg);
        return result;
    }


    //编写方法-返回需要的Result对象-表示失败的Result
    public static Result error(String code, String msg) {
        Result result = new Result<>();
        result.setCode(code);
        result.setMsg(msg);
        return result;
    }

    //编写方法-返回需要的Result对象-表示失败的Result,同时可以携带数据

    public static <T> Result<T> error(String code, String msg, T data) {
        Result<T> result = new Result<>(data);
        result.setCode(code);
        result.setMsg(msg);
        return result;
    }
}

创建接口:/dao/MemberDao.java 

@Mapper
public interface MemberDao {

    //定义方法
    //根据id返回member数据
    public Member queryMemberById(Long id);
    //添加member
    public int save(Member member);
}

 创建resources/mapper/MemberMapper.xml

<mapper namespace="com.wyxedu.springcloud.dao.MemberDao">

    <!--配置实现queryMemberById
    1. 这里可以使用 resultType="Member"
    2. 当然也可以使用resultMap="自定义的resultMap", 这里我们使用resultMap
    3. 如何配置一个resultMap ,在mybatis讲过的,请回顾
    -->
    <resultMap id="BaseResultMap" type="Member">
        <id column="id" property="id" jdbcType="BIGINT"></id>
        <id column="name" property="name" jdbcType="VARCHAR"></id>
        <id column="pwd" property="pwd" jdbcType="VARCHAR"></id>
        <id column="mobile" property="mobile" jdbcType="VARCHAR"></id>
        <id column="email" property="email" jdbcType="VARCHAR"></id>
        <id column="gender" property="gender" jdbcType="TINYINT"></id>
    </resultMap>

    <select id="queryMemberById" parameterType="Long" resultMap="BaseResultMap">
        SELECT * FROM `member` WHERE `id`=#{id}
    </select>

    <!--配置实现save -->
    <insert id="save" parameterType="Member" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO `member`(`NAME`,`pwd`,`mobile`,`email`,`gender`)
        VALUES(#{name}, MD5(#{pwd}), #{mobile}, #{email}, #{gender});
    </insert>
</mapper

完成测试 

创建接口:service/MemberService.java

public interface MemberService {
    //根据id返回member
    public Member queryMemberById(Long id);

    //添加member
    public int save(Member member);
}

创建/impl/MemberServiceImpl.java

@Service
public class MemberServiceImpl implements MemberService {

    //装配MemberDao
    @Resource
    private MemberDao memberDao;
    @Override
    public Member queryMemberById(Long id) {
        return memberDao.queryMemberById(id);
    }
    @Override
    public int save(Member member) {
        return memberDao.save(member);
    }
}

创建springcloud/controller/MemberController.java

@RestController
@Slf4j
public class MemberController {

    //装配MemberService
    @Resource
    private MemberService memberService;

    //添加方法/接口
    //说明
    //1. 我们的前端如果是以json格式来发送添加信息Member, 那么我们需要使用@RequestBody
    //   , 才能将数据封装到对应的bean, 同时保证http的请求头的 content-type是对应
    //2. 如果前端是以表单形式提交了,则不需要使用@RequestBody, 才会进行对象参数封装, 同时保证
    //   http的请求头的 content-type是对应
    @PostMapping("/member/save")
    public Result save(@RequestBody Member member) {
        log.info("service-provider member={}", member);
        int affected = memberService.save(member);
        if (affected > 0) { //说明添加成功
            return Result.success("添加会员成功", affected);
        } else {
            return Result.error("401", "添加会员失败");
        }
    }

    //查询的方法/接口
    //这里使用url占位符+@PathVariable
    @GetMapping("/member/get/{id}")
    public Result getMemberById(@PathVariable("id") Long id, HttpServletRequest request) {

        Member member = memberService.queryMemberById(id);

        //使用Result把查询到的结果返回
        if (member != null) {
           
            return Result.success("查询会员成功 member-service-provider-10000", member);
        } else {
            return Result.error("402", "ID= " + id + "不存在");
        }

    }
}

完成测试 图片在上面已经有了这里就不再重复截图了

注意事项和细节

1、我们的前端如果是以json 格式来发送添加信息furn,那么我们需要使用@RequestBody,才能将数据封装到对应的bean, 同时保证http 的请求头的content-type 是对应

2、如果前端是以表单形式提交了/或者是以parameters,则不需要使用@RequestBody, 才会进行对象参数封装, 同时保证http 的请求头的content-type 是对应

3、在进行SpringBoot 应用程序测试时,引入的JUnit 是org.junit.jupiter.api.Test

4、在运行程序时,一定要确保你的XxxxMapper.xml 文件被自动放到的target 目录classes 指定目录

 

创建使用会员微服务模块-service consumer 

示意图

浏览器: http://localhost/member/consumer/get/1

 

-测试添加会员: http://localhost/member/consumer/save

 创建Moduel(member-service-consumer-80) & 完成配置

后面就是老样子就不再重复了前面已经完整的介绍了创建流程

父工程的pom.xml-会做相应变化,管理member-service-consumer-80 微服务子模块

 修改member-service-consumer-80 的pom.xml , 加入相关依赖

<!-- 因为是子模块,因此不需要指定groupId 了,从父工程继承-->
<artifactId>member-service-consumer-80</artifactId>
<dependencies>
<dependency>
    <!--引入web-starter 说明我们使用版本仲裁(从父项目继承了版本)
-->
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <!-- 如果在子工程/模块指定了version,则以指定为准-->
</dependency>
<dependency>
    <!--说明:starter-actuator 是springboot程序的监控系统, 可以实现系统的健康检测
        可以通过http://localhost:10000/actuator 看到相关的连接,和信息
        -->
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-l-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
</dependencies>

创建resources/application.yml

server:
  port: 80

创建主启动类MemberConsumerApplication.java

@SpringBootApplication
public class MemberConsumerApplication {
    public static void main(String[] args) {

        SpringApplication.run(MemberConsumerApplication.class,args);
    }

 业务实现
entity

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Member{
    private Long id;
    private String name;
    private String pwd;
    private String mobile;
    private String email;
    private Integer gender;
}

创建entity/Result.java

这个我的博客boot+vue有介绍过

/**
 * Result: 返回结果对象: 以json格式返回
 * 我的springboot + vue项目的博客中有介绍过
 * * 说明
 * * 1. Result<T> 自定义泛型类
 * * 2. Result<T> 对象就是后端返回给前端的数据,是以json格式返回
 */
public class Result<T> {
    private String code; //状态码
    private String msg; //对状态说明
    private T data; // 返回时,携带的数据, 为了扩展性好,使用泛型

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }


    //无参构造器
    public Result() {

    }

    //带参构造器-指定返回的data
    public Result(T data) {
        this.data = data;
    }

    //编写方法-返回需要的Result对象-表示成功的Result
    public static Result success() {
        Result result = new Result<>();
        result.setCode("200");
        result.setMsg("success");
        return result;
    }

    //编写方法-返回需要的Result对象-表示成功的Result,同时可以携带数据
    //如果需要在static方法使用泛型,需要在 static <T>
    public static <T> Result<T> success(T data) {
        Result<T> result = new Result<>(data);
        result.setCode("200");
        result.setMsg("success");
        return result;
    }

    //编写方法-返回需要的Result对象-表示成功的Result,同时可以携带数据和指定msg
    //如果需要在static方法使用泛型,需要在 static <T>
    public static <T> Result<T> success(String msg, T data) {
        Result<T> result = new Result<>(data);
        result.setCode("200");
        result.setMsg(msg);
        return result;
    }


    //编写方法-返回需要的Result对象-表示失败的Result
    public static Result error(String code, String msg) {
        Result result = new Result<>();
        result.setCode(code);
        result.setMsg(msg);
        return result;
    }

    //编写方法-返回需要的Result对象-表示失败的Result,同时可以携带数据

    public static <T> Result<T> error(String code, String msg, T data) {
        Result<T> result = new Result<>(data);
        result.setCode(code);
        result.setMsg(msg);
        return result;
    }
}

注入RestTemplate

基本介绍

1、RestTemplate 是Spring 提供的用于访问Rest 服务的模板类

2、RestTemplate 提供了多种便捷访问远程Http 服务的方法

3、说明:小伙伴可以这样理解, 通过RestTemplate, 我们可以发出http 请求(支持Restful 风格) 去调用Controller 提供的API 接口, 就像我们使用浏览器发出http 请求,调用该API 接口一样

4、使用简单便捷

● 官网地址

https://docs.spring.io/spring-framework/docs/5.2.2.RELEASE/javadoc-api/org/springframe
work/web/client/RestTemplate.html

创建配置类: config/CustomizationBean.java

/**
 * CustomizationBean: 配置类
 * 配置注入RestTemplate bean/对象
 */
@Configuration
public class CustomizationBean {

    //说明: 配置注入RestTemplate bean/对象
    @Bean
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

修改Controller

@RestController
@Slf4j
public class MemberConsumerController {
    public static final String
            MEMBER_SERVICE_PROVIDER_URL = "http://localhost:10000";
    @Resource
    private RestTemplate restTemplate;

    @PostMapping("/member/consumer/save")
    public Result<Member> save(Member member) {
        /**
         * 解读
         * 1. MEMBER_SERVICE_PROVIDER_URL + "/member/save" 请求的url
         * 2. member 请求参数
         * 3. Result.class http 响应被转换的对象类型
         */
        return restTemplate.postForObject(MEMBER_SERVICE_PROVIDER_URL 
                + "/member/save", member, Result.class);
    }

    @GetMapping("/member/consumer/get/{id}")
    public Result<Member> getMemberById(@PathVariable("id") Long id) {
        return restTemplate.getForObject(MEMBER_SERVICE_PROVIDER_URL
                + "/member/get/" + id, Result.class);
    }

完成测试

 首先启动微服务模块: member-service-provider-10000 和member-service-consumer-80

测试图已经在开头这里就不再重复显示

注意事项和使用细节

如果member-service-consumer-80 启动报错: springBoot 启动If you want an embedded
database (H2, HSQL or Derby), please put it on the classpath

添加会员数据库中为null 的解决方案

 

开启Run DashBoard

什么是Run Dashboard
当springcloud 的服务有多个时,管理多个服务的启动使用run 会不好管理,这样我们就可以使用RunDashboard

新版的2020 的IDEA 当你同时启动两个微服务时,不会弹出启动Run Dashboard 窗口的提示

是因为IDEA2020 将Run Dashboard 添加到控制台Service 中开启Run Daahboard/Service 的步骤 

 

 

<component name="RunDashboard">
    <option name="configurationTypes">
        <set>
            <option value="SpringBootApplicationConfigurationType" />
        </set>
    </option>
    <option name="ruleStates">
        <list>
            <RuleState>
                <option name="name" value="ConfigurationTypeDashboardGroupingRule" />
            </RuleState>
            <RuleState>
                <option name="name" value="StatusDashboardGroupingRule" />
            </RuleState>
        </list>
    </option>
</component>

重新启动idea2020.2 , 会看到如下界面, 如果没有看到这个Services, 参考第3 步添加一下即可

如果没有看到这个Services, 添加一下即可

  

 启动你的微服务,就会在Service 面板上看到各个微服务模块, 也可以进行管理

提醒: 不同版本的IDEA 开启Run DashBoard 有区别,如果和老师IDEA 版本不同,百度下解决,不难

 

创建共用模块-供其它模块使用 

思路分析/图解

1、创建Moduel & 完成配置
2、创建entity, 把共用的实体类放到对应的包下
3、完成测试 

创建e_commerce_center-common-api

后面就是老样子就不再重复了前面已经完整的介绍了创建流程

 父工程的pom.xml-会做相应变化,管理e_commerce_center-common-api子模块

修改e_commerce_center-common-api 的pom.xml 

    <!--引入公共模块需要的依赖-->
    <dependencies>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <!--
                 解读<optional>true</optional>:
                 1. true表示两个项目之间依赖不传递
                 2. 可以这里理解<optional>true</optional>: 防止将该依赖传递到其他模块中
                    说的再具体一点,比如member-service-consumer-80模块依赖了本项目,
                    那么本项目不会把lombok 传递给 member-service-consumer-80
                 3. 不设置optional或者optional是false,表示传递依赖
            -->
            <optional>true</optional>
        </dependency>
    </dependencies>

抽取共用API/类

entity【从前面的工程拷贝即可】

创建Member 类 

Serializable 加上,后面可能使用

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Member implements Serializable {
    private Long id;
    private String name;
    private String pwd;
    private String mobile;
    private String email;
    private Integer gender;

创建entity/Result.java

/**
 * Result: 返回结果对象: 以json格式返回
 * 我我的springboot + vue项目的博客中有介绍过
 * * 说明
 * * 1. Result<T> 自定义泛型类
 * * 2. Result<T> 对象就是后端返回给前端的数据,是以json格式返回
 */
public class Result<T> {
    private String code; //状态码
    private String msg; //对状态说明
    private T data; // 返回时,携带的数据, 为了扩展性好,老师使用泛型

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }


    //无参构造器
    public Result() {

    }

    //带参构造器-指定返回的data
    public Result(T data) {
        this.data = data;
    }

    //编写方法-返回需要的Result对象-表示成功的Result
    public static Result success() {
        Result result = new Result<>();
        result.setCode("200");
        result.setMsg("success");
        return result;
    }

    //编写方法-返回需要的Result对象-表示成功的Result,同时可以携带数据
    //如果需要在static方法使用泛型,需要在 static <T>
    public static <T> Result<T> success(T data) {
        Result<T> result = new Result<>(data);
        result.setCode("200");
        result.setMsg("success");
        return result;
    }

    //编写方法-返回需要的Result对象-表示成功的Result,同时可以携带数据和指定msg
    //如果需要在static方法使用泛型,需要在 static <T>
    public static <T> Result<T> success(String msg, T data) {
        Result<T> result = new Result<>(data);
        result.setCode("200");
        result.setMsg(msg);
        return result;
    }


    //编写方法-返回需要的Result对象-表示失败的Result
    public static Result error(String code, String msg) {
        Result result = new Result<>();
        result.setCode(code);
        result.setMsg(msg);
        return result;
    }

    //编写方法-返回需要的Result对象-表示失败的Result,同时可以携带数据

    public static <T> Result<T> error(String code, String msg, T data) {
        Result<T> result = new Result<>(data);
        result.setCode(code);
        result.setMsg(msg);
        return result;
    }

使用Maven 打包成jar

1、操作步骤

注意如果没有第一步也没有多大的关系 这第一步的作用是速度快一点 高版本的iead可能没有

 

2、可以解压e_commerce....jar 可以看到打包后的.class 文件 

工程重构

在member-service-consumer-80 引入e_commerce_center-common-api-1.0-SNAPSHOT.jar

1. 删除原来的entity 包
2. 修改pom.xml 

<!-- 引入e_commerce_center-common-api -->
<dependency>
<groupId>com.hspedu.springcloud</groupId>
<artifactId>e_commerce_center-common-api</artifactId>
<version>${project.version}</version>
</dependency>

在member-service-provider-10000 引入e_commerce_center-common-api-1.0-SNAPSHOT.jar

1. 删除原来的entity 包
2. 修改pom.xml

<!-- 引入e_commerce_center-common-api -->
<dependency>
<groupId>com.hspedu.springcloud</groupId>
<artifactId>e_commerce_center-common-api</artifactId>
<version>${project.version}</version>
</dependency>

完成测试

首先启动微服务模块: member-service-provider-10000 和member-service-consumer-80

浏览器: http://localhost/member/consumer/get/1

PostMan:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/555736.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java.lang.NoClassDefFoundError: org/apache/logging/log4j/util/ReflectionUtil

具体问题描述如下&#xff1a; SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/D:/maven/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.6.2/log4j-slf4j-impl-2.6.2.jar!/org/slf4j/impl/StaticLoggerBinder.class] SL…

【Spring - beans】 BeanDefinition 源码

目录 1. BeanDefinition 1.1 AbstractBeanDefinition 1.2 RootBeanDefinition 1.3 ChildBeanDefinition 1.4 GenericBeanDefinition 2. BeanDefinitionReader 2.1 AbstractBeanDefinitionReader 2.2 XmlBeanDefinitionReader 2.3 GroovyBeanDefinitionReader 2.4 Pro…

(跨模态)AI作画——使用stable-diffusion生成图片

AI作画——使用stable-diffusion生成图片 0. 简介1. 注册并登录huggingface2. 下载模型3. 生成 0. 简介 自从DallE问世以来&#xff0c;AI绘画越来越收到关注&#xff0c;从最初只能画出某些特征&#xff0c;到越来越逼近真实图片&#xff0c;并且可以利用prompt来指导生成图片…

软件测试面试题——数据库知识

1、要查询每个商品的入库数量&#xff0c;可以使用以下SQL语句&#xff1a; SELECT 商品编号, SUM(入库数量) AS 入库数量 FROM Stock GROUP BY 商品编号;这将从Stock表中选择每个商品的入库数量&#xff0c;并使用SUM函数对入库数量进行求和。结果将按照商品编号进行分组&…

数据宝藏与精灵法师:探秘Elf擦除魔法的奇幻故事

在数字领域的奇幻王国中&#xff0c;大家视数据为宝藏。作为奇幻王国的国王&#xff0c;在他的宝库中&#xff0c;自然是有着无数的数据宝藏。这么多的数据宝藏&#xff0c;却让国王发难了。因为宝库有限&#xff0c;放不下这么多数据宝藏。因此&#xff0c;国王广招天下的精灵…

【备战秋招】每日一题:3月18日美团春招第三题:题面+题目思路 + C++/python/js/Go/java带注释

2023大厂笔试模拟练习网站&#xff08;含题解&#xff09; www.codefun2000.com 最近我们一直在将收集到的各种大厂笔试的解题思路还原成题目并制作数据&#xff0c;挂载到我们的OJ上&#xff0c;供大家学习交流&#xff0c;体会笔试难度。现已录入200道互联网大厂模拟练习题&…

简易someip服务发现SD报文演示

环境 $ cat /etc/os-release PRETTY_NAME"Ubuntu 22.04.1 LTS" NAME"Ubuntu" VERSION_ID"22.04" VERSION"22.04.1 LTS (Jammy Jellyfish)" VERSION_CODENAMEjammy IDubuntu ID_LIKEdebian HOME_URL"https://www.ubuntu.com/"…

chatgpt赋能Python-pythonsum

Pythonsum&#xff1a;优秀的Python算法包介绍 Pythonsum是Python语言的一个优秀的算法包&#xff0c;具有很高的可重用性和性能&#xff0c;支持大规模数据处理和复杂算法实现。本文将为大家介绍Pythonsum的基本功能和优势。 Pythonsum的基本功能 Pythonsum提供了一系列丰富…

华为OD机试真题 Java 实现【对称字符串】【2023Q2 200分】

一、题目描述 对称就是最大的美学&#xff0c;现有一道关于对称字符串的美学。 已知&#xff1a; 第 1 个字符串&#xff1a;R 第 2 个字符串&#xff1a;BR 第 3 个字符串&#xff1a;RBBR 第 4 个字符串&#xff1a;BRRBRBBR 第 5 个字符串&#xff1a;RBBRBRRBBRRBRBBR …

扑克牌大小OJ题

题目链接 扑克牌大小_牛客题霸_牛客网 题目完整代码 #include <iostream> #include<string> #include<algorithm> using namespace std;// left_str 左边牌 // right_str 右边牌// left_count 左边牌数 // right_count 右边牌数// left_first 左边第一个牌…

chatgpt赋能Python-pythonsep怎么用

Python在SEO中的应用 Python一直是广受欢迎的编程语言之一&#xff0c;它拥有强大的功能和易于使用的特性&#xff0c;使得它成为了许多开发人员们的首选。“Pythonsep”是Python在SEO中的应用&#xff0c;它可以帮助用户更好地优化自己的网站&#xff0c;让网站更容易被用户发…

搭建python web环境----Django

第一步&#xff1a;安装Django 1.进入cmd&#xff1a;pip install django -i https://pypi.tuna.tsinghua.edu.cn/simple 2.检测版本&#xff1a; 第二步&#xff1a;配置环境变量 1.查找python安装位置: 2.打开django文件夹中bin文件夹&#xff1a; 查看django的安装位置&am…

火爆CV圈的SAM是什么?

SAM是什么 前言 最近几周&#xff0c;人工智能的圈子里都在讨论SAM&#xff08;Segment Anything Model&#xff09;&#xff0c;一个号称&#xff08;零样本&#xff09;分割一切的图像分割模型。 图&#xff1a;Segment Anything Demo 2023年4月6号&#xff0c;Meta AI发布…

npm install(报错)

1、npm install 报错&#xff08;如图&#xff09; WARN ERESOLVE overriding peer dependency npm WARN While resolving: intervolga/optimize-cssnano-plugin1.0.6 npm WARN Found: webpack3.12.0 npm WARN node_modules/webpack npm WARN peer webpack"^2.0.0 || ^3…

spring源码学习

1.xmlBeanFactory对defaultListableBeanFactory类进行扩展&#xff0c;主要用于从XML文档中获取BeanDefinition&#xff0c;对于注册及获取bean都是使用从父类DefaultListableBeanFactory继承的方法去实现。 xmlBeanFactory 主要是使用reader属性对资源文件进行读取和注册。 2.…

VMware ESXi 6.7 U3 Final - ESXi 6 系列最终版下载

VMware ESXi 6.7 U3 Final - ESXi 6 系列最终版下载 VMware ESXi 6 Standard 请访问原文链接&#xff1a;https://sysin.org/blog/vmware-esxi-6/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org VersionRelease NameRelease …

APIO2023 游记

GDOI 和 GDKOI 的游记都咕咕咕了&#xff0c;而且都炸了&#xff0c;APIO 的游记提前发&#xff0c;就是要破釜沉舟。 我是线上选手。 Day -7 我们原题检测&#xff0c;阿克了&#xff0c;毕竟是原题&#xff0c;虽然有两道博弈论黑题确实挺毒瘤的。 教练让我做 APIO2012 的…

centos8安装mysql8

本次介绍捆绑包rpm方式安装mysql 首先到mysql官网:MySQL 1.下载捆绑包 2.上传至服务器 3.解压 tar -xvf mysql捆绑包.tar 4.重点来了,按照以下顺序分别安装(命令中的版本号按照自己下载的版本调整) rpm -ivh mysql-community-common-8.0.26-1.el7.x86_64.rpm rpm -ivh my…

东南亚市场攻略:如何利用海外网红实现品牌曝光与销售增长

在当今数字化时代&#xff0c;社交媒体的兴起改变了品牌推广和市场开发的方式。尤其是在东南亚地区&#xff0c;网红营销迅速发展&#xff0c;成为品牌开发该地市场的重要策略之一。本文Nox聚星将和大家详细探讨出海品牌该如何利用海外网红营销来开发东南亚市场。 ​一、东南亚…

怎么做邮件营销?邮件营销必备攻略

电子邮件营销是与受众沟通、建立关系和推动转化有效的方式之一。然而&#xff0c;撰写有效的电子邮件营销活动需要创造力和方法技巧的结合。做好电子邮件营销能够为企业带来长期的客源&#xff0c;并为其培养稳定优质的客户&#xff0c;为企业带来长期收益。在这篇文章中&#…