Spring Cloud【Finchley】实战-04将订单微服务与商品微服务分别拆分为多模块

简介: Spring Cloud【Finchley】实战-04将订单微服务与商品微服务分别拆分为多模块

Spring Cloud【Finchley】专栏


如果还没有系统的学过Spring Cloud ,先到我的专栏去逛逛吧

Spring Cloud 【Finchley】手札


概述


上篇博文 Spring Cloud实战-03订单微服务与商品微服务之间的调用 我们虽然打通了订单流程,但是还是有些问题需要去修改和完善下

  • 问题一:将数据表映射的实体类暴露出去了,建议最好再封装一层

20190325235349656.png


问题二:同一个对象在不同微服务之间重复定义

我们在Order微服中使用Feign调用Product微服务提供的一些接口时 ,原本属于product微服务的Product和CartDTO类为了不报错却不得不在Order为服务中重复定义,维护较为麻烦。 原则是:这些类该属于哪个模块就在哪个模块定义。


20190326000026835.png

20190325235656459.png


问题三: 将对方的服务定义到自己的服务中

order和product 可能是两个小组来开发,而我们要在order微服中将product微服务的请求的url写到自己的为服务中,将对方的服务定义到自己的服务中是不是不太合理? 应该自己管理自己的对外接口,暴露出去供外部调用者使用。


20190326000800205.png


那如何解决上述问题呢? 答案就是利用maven的多模块技术,将服务拆分为多个子模块。

如何拆分SpringBoot项目,阿里小马哥有个视频讲的挺好,移步:https://www.imooc.com/video/16354

或者参考我以前的博文 : Maven父子工程的搭建


Product微服务功能分析及多模块拆分

拆分原则

我们将Product划分为3个子模块

  • product Server : 所有业务逻辑
  • product Client : 对外暴露的接口(目前有查询商品和扣减库存)
  • product Common : 公用的对象

三者的依赖关系,

product Server 依赖 product Common

product Client 依赖 product Common

那动手拆分起来吧


Step1. 调整主(父)工程的工程类型 packaging为pom


将packaging 由 jar 改为 pom

<packaging>jar</packaging>

调整为:

<packaging>pom</packaging>



20190326010051718.png


Step2. 新建子模块

选中artisan-product工程 右键 New — Module ,

一定要选Maven


20190326010129269.png


啥都不用勾选,默认下一步


20190326010237943.png


Next


20190326010252477.png


确认下,默认即可,点击 Finish结束 。


回头查看父工程的pom.xml 已经新增了 modules节点如下信息

20190326010403687.png

再看下新建的子模块 product-server



20190326010524248.png


未完待续…

2019-03-31续

经过了一周丧心病狂的加班,周末终于有时间了,那我们继续吧

先建好3个子Module(方式同上),然后再将代码按照模块的划分分别整合到各个子模块中。


20190331182132960.png


模块已经建好,根据确定好的拆分原则那将代码按照模块的划分分别整合到各个子模块中吧。

几个注意事项:

  1. 凡是版本的定义,都建议放在最外层的dependencyManagement中,方便做到统一管理
  2. 依赖的模块,需要先mvn install ,其他模块才可以正确的引用


父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.artisan</groupId>
    <artifactId>artisan-product</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <modules>
        <module>product-server</module>
        <module>product-client</module>
        <module>product-common</module>
    </modules>
    <packaging>pom</packaging>
    <name>artisan-product</name>
    <description>Product</description>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <productcommon.version>0.0.1-SNAPSHOT</productcommon.version>
        <springcloud.version>Finchley.RELEASE</springcloud.version>
    </properties>
    <!-- 凡是版本的定义,都建议放在最外层的dependencyManagement中,方便做到统一管理 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${springcloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- product-server和product-client都需要依赖该模块,
            在这里定义版本之后,在server和client模块引用的话就无需再加上version了,方便统一管理 -->
            <dependency>
                <groupId>com.artisan</groupId>
                <artifactId>product-common</artifactId>
                <version>${productcommon.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>


product common

主要是解决问题一将数据表映射的实体类暴露出去了,建议最好再封装一层



20190401235500228.png


pom.xml

<?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>artisan-product</artifactId>
        <groupId>com.artisan</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>product-common</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
</project>


product client


主要是解决问题二同一个对象在不同微服务之间重复定义以及问题三自己的服务写到自己的工程中。

那么我们就将属于product微服务的ProductClient定义在该模块中


20190401235745178.png


product client 依赖 product common

<?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>artisan-product</artifactId>
        <groupId>com.artisan</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>product-client</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>com.artisan</groupId>
            <artifactId>product-common</artifactId>
        </dependency>
    </dependencies>
</project>
package com.artisan.product.client;
import com.artisan.product.common.DecreaseStockInput;
import com.artisan.product.common.ProductOutput;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import java.util.List;
@FeignClient(name="ARTISAN-PRODUCT")
public interface ProductClient {
    @PostMapping("/product/productListForOrder")
    List<ProductOutput> getProductForOrder(List<String> productIdList);
    /**
     * 这里我们就不用CartDTO了,因为它属于Order工程,我们这里自己在ProductCommon中自己维护一个DTO类
     * DecreaseStockInput
     * @param decreaseStockInputList
     */
    @PostMapping("/product/decreseProduct")
    void decreseProduct(List<DecreaseStockInput> decreaseStockInputList);
}

product server

product server也依赖 product common

<?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>artisan-product</artifactId>
        <groupId>com.artisan</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>product-server</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</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>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.artisan</groupId>
            <artifactId>product-common</artifactId>
        </dependency>
    </dependencies>
    <!--打包 放在product-server中-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

20190402000101510.png


ProductController


20190402000302927.png


ProductService 接口

2019040200075684.png


然后删掉些之前的引用即可。


Order微服务的改造

同上,就不多赘述了,详见Github,

目前order-client 和 order-common没有啥需求,先写个空的吧,后续根据需求逐步完善,


20190402001016663.png

其中order-server模块需要说明的是:

因为要调用商品微服务来查询商品和扣减库存,所以要依赖product-client包

    <dependency>
            <groupId>com.artisan</groupId>
            <artifactId>product-client</artifactId>
        </dependency>

同时为了让order server微服务启动时实例化Feign接口,需要配置扫描基包 (因为他们不在一个工程的同一级或者子孙级目录中)

@EnableFeignClients(basePackages="com.artisan.product.client")


20190402002232442.png


测试

启动注册中心,通过product-server和order-server中的main函数启动俩微服务,

下单

20190402001234684.png

select * from artisan_order a where a.order_id = '1554135137371873119';
select * from order_detail a  where a.order_id = '1554135137371873119';

20190402001420354.png20190402001445164.png


代码


Github

https://github.com/yangshangwei/springcloud-o2o/tree/master/artisan-product

https://github.com/yangshangwei/springcloud-o2o/tree/master/artisan_order

相关文章
|
3月前
|
人工智能 Java 数据库
飞算 JavaAI:革新电商订单系统 Spring Boot 微服务开发
在电商订单系统开发中,传统方式耗时约30天,需应对复杂代码、调试与测试。飞算JavaAI作为一款AI代码生成工具,专注于简化Spring Boot微服务开发。它能根据业务需求自动生成RESTful API、数据库交互及事务管理代码,将开发时间缩短至1小时,效率提升80%。通过减少样板代码编写,提供规范且准确的代码,飞算JavaAI显著降低了开发成本,为软件开发带来革新动力。
|
19天前
|
Java API 微服务
Java 21 与 Spring Boot 3.2 微服务开发从入门到精通实操指南
《Java 21与Spring Boot 3.2微服务开发实践》摘要: 本文基于Java 21和Spring Boot 3.2最新特性,通过完整代码示例展示了微服务开发全流程。主要内容包括:1) 使用Spring Initializr初始化项目,集成Web、JPA、H2等组件;2) 配置虚拟线程支持高并发;3) 采用记录类优化DTO设计;4) 实现JPA Repository与Stream API数据访问;5) 服务层整合虚拟线程异步处理和结构化并发;6) 构建RESTful API并使用Springdoc生成文档。文中特别演示了虚拟线程配置(@Async)和StructuredTaskSco
71 0
|
1月前
|
负载均衡 Java API
基于 Spring Cloud 的微服务架构分析
Spring Cloud 是一个基于 Spring Boot 的微服务框架,提供全套分布式系统解决方案。它整合了 Netflix、Zookeeper 等成熟技术,通过简化配置和开发流程,支持服务发现(Eureka)、负载均衡(Ribbon)、断路器(Hystrix)、API网关(Zuul)、配置管理(Config)等功能。此外,Spring Cloud 还兼容 Nacos、Consul、Etcd 等注册中心,满足不同场景需求。其核心组件如 Feign 和 Stream,进一步增强了服务调用与消息处理能力,为开发者提供了一站式微服务开发工具包。
118 0
|
4月前
|
前端开发 Java 数据库
微服务——SpringBoot使用归纳——Spring Boot集成Thymeleaf模板引擎——Thymeleaf 介绍
本课介绍Spring Boot集成Thymeleaf模板引擎。Thymeleaf是一款现代服务器端Java模板引擎,支持Web和独立环境,可实现自然模板开发,便于团队协作。与传统JSP不同,Thymeleaf模板可以直接在浏览器中打开,方便前端人员查看静态原型。通过在HTML标签中添加扩展属性(如`th:text`),Thymeleaf能够在服务运行时动态替换内容,展示数据库中的数据,同时兼容静态页面展示,为开发带来灵活性和便利性。
117 0
|
4月前
|
XML Java 数据库连接
微服务——SpringBoot使用归纳——Spring Boot集成MyBatis——基于 xml 的整合
本教程介绍了基于XML的MyBatis整合方式。首先在`application.yml`中配置XML路径,如`classpath:mapper/*.xml`,然后创建`UserMapper.xml`文件定义SQL映射,包括`resultMap`和查询语句。通过设置`namespace`关联Mapper接口,实现如`getUserByName`的方法。Controller层调用Service完成测试,访问`/getUserByName/{name}`即可返回用户信息。为简化Mapper扫描,推荐在Spring Boot启动类用`@MapperScan`注解指定包路径避免逐个添加`@Mapper`
123 0
|
4月前
|
Java 测试技术 微服务
微服务——SpringBoot使用归纳——Spring Boot中的项目属性配置——少量配置信息的情形
本课主要讲解Spring Boot项目中的属性配置方法。在实际开发中,测试与生产环境的配置往往不同,因此不应将配置信息硬编码在代码中,而应使用配置文件管理,如`application.yml`。例如,在微服务架构下,可通过配置文件设置调用其他服务的地址(如订单服务端口8002),并利用`@Value`注解在代码中读取这些配置值。这种方式使项目更灵活,便于后续修改和维护。
66 0
|
4月前
|
SQL Java 数据库连接
微服务——SpringBoot使用归纳——Spring Boot使用slf4j进行日志记录—— application.yml 中对日志的配置
在 Spring Boot 项目中,`application.yml` 文件用于配置日志。通过 `logging.config` 指定日志配置文件(如 `logback.xml`),实现日志详细设置。`logging.level` 可定义包的日志输出级别,例如将 `com.itcodai.course03.dao` 包设为 `trace` 级别,便于开发时查看 SQL 操作。日志级别从高到低为 ERROR、WARN、INFO、DEBUG,生产环境建议调整为较高级别以减少日志量。本课程采用 yml 格式,因其层次清晰,但需注意格式要求。
238 0
|
1月前
|
Prometheus 监控 Cloud Native
Spring Boot 可视化监控
本文介绍了如何通过Spring Actuator、Micrometer、Prometheus和Grafana为Spring Boot应用程序添加监控功能。首先创建了一个Spring Boot应用,并配置了Spring Actuator以暴露健康状态和指标接口。接着,利用Micrometer收集应用性能数据,并通过Prometheus抓取这些数据进行存储。最后,使用Grafana将Prometheus中的数据可视化,展示在精美的仪表板上。整个过程简单易行,为Spring Boot应用提供了基本的监控能力,同时也为后续扩展更详细的监控指标奠定了基础。
131 2
|
4月前
|
缓存 NoSQL Java
基于SpringBoot的Redis开发实战教程
Redis在Spring Boot中的应用非常广泛,其高性能和灵活性使其成为构建高效分布式系统的理想选择。通过深入理解本文的内容,您可以更好地利用Redis的特性,为应用程序提供高效的缓存和消息处理能力。
257 79

热门文章

最新文章