ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

后端工程架构系列篇(一):单应用多模块(按业务拆分)

2022-01-02 12:33:18  阅读:179  来源: 互联网

标签:架构 拆分 service common 模块 import mmyk com


@

目录
,适合中小团队)

目录

简单聊聊

单体应用 VS 微服务,如何选?务必要根据公司开发人员数量和系统业务宽度来进行选择,如果你是为了简历好看或者学习,另当别论。微服务就是拆散了技术成熟的单体应用,然后又借助外部工具重新把他们粘起来,如通信、事务、部署、日志等,下一篇就会涉及,到时候我们就用阿里工具箱来演示,如dubbo、nacos、seata等。。本期介绍一个折中的选择,单应用多模块架构方式,后期想做微服务也会非常方便,无需推翻。

适用对象

绝大多数公司采用单应用多模块架构来开发足矣

  1. 中小团队(百人以内)
  2. 高内聚系统
  3. 分组分模块开发

正式开始

环境组件:以springboot2+hibernate为基础,java:11,开发工具:idea,数据库:mysql5
演示业务:创建订单(公共接口)->扣除商品库存(公共接口)->增加商品销量(私有接口),如果库存不足就进行事务回滚。订单和商品是2个模块。包含service级的基础校验@Validated

  1. 完整的项目工程结构
    在这里插入图片描述

  2. 创建根项目
    根项目使用spring的脚手架,其他子模块就选择Maven
    在这里插入图片描述

在这里插入图片描述

  1. 创建common模块
    new->module在这里插入图片描述
    直接next
    在这里插入图片描述

在这里插入图片描述
common模块的结构,公共接口、公共出参、公共入参等
在这里插入图片描述

  1. 创建web模块
    new->module在这里插入图片描述
    直接next
    在这里插入图片描述
    在这里插入图片描述

web模块结构图,包含:控制器、过滤器、拦截器,配置文件yml,启动类等,以及权限校验、swagger文档等,类似网关的作用,在这里插入图片描述
注意:web模块为启动类,在pom.xml添加以下代码,可以在根项目里复制过来,并且需要把根项目这段代码去掉

<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

这是OrderController类,可以一个服务对应一个controller

package com.mmyk.scli.web.controller;

import com.mmyk.scli.common.request.CreateOrderRequest;
import com.mmyk.scli.common.service.OrderCommonService;
import com.mmyk.scli.web.vo.ResponseVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@Tag(name = "订单")
@RestController
public class OrderController {

    @Autowired
    private OrderCommonService orderCommonService;

    @Operation(summary = "创建订单")
    @PostMapping("/order.create")
    public Object prod(@RequestBody CreateOrderRequest param) {
        return ResponseVO.ok(orderCommonService.createOrder(param));
    }
}

  1. 创建service模块
    new->module在这里插入图片描述
    直接next
    在这里插入图片描述
    在这里插入图片描述
    service模块结构图,作为所有业务模块的父模块
    在这里插入图片描述
    service模块下: 创建商品子模块,该模块可以建立自己的yml
    注意Parent,选择service模块
    在这里插入图片描述

在这里插入图片描述
该实现有2个接口,一个为common模块下公共接口,一个为本模块内的接口,第二个只供本模块内部使用。
在这里插入图片描述
这是订单子模块的 orderServiceImpl,创建订单

package com.mmyk.slic.service.order.service.impl;

import com.mmyk.scli.common.request.CreateOrderRequest;
import com.mmyk.scli.common.request.DeductStockRequest;
import com.mmyk.scli.common.response.CreateOrderResponse;
import com.mmyk.scli.common.response.DeductStockResponse;
import com.mmyk.scli.common.service.OrderCommonService;
import com.mmyk.scli.common.service.ProductCommonService;
import com.mmyk.slic.service.order.dao.OrderDao;
import com.mmyk.slic.service.order.entiy.Order;
import com.mmyk.slic.service.order.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

@Slf4j
@Validated
@Service
public class OrderServiceImpl implements OrderCommonService, OrderService {
    @Autowired
    private OrderDao orderDao;

    @Autowired
    private ProductCommonService productCommonService;

    @Transactional
    @Override
    public CreateOrderResponse createOrder(CreateOrderRequest request) {
        log.info("OrderServiceImpl.createOrder() ok");
        Long count = orderDao.count();
        log.info("当前order表总行数:{}", count);

        Order order = new Order();
        order.setOrderNumber("100001");
        order.setProductId(request.getProductId());
        order = orderDao.save(order);
        CreateOrderResponse createOrderResponse = new CreateOrderResponse();
        createOrderResponse.setOrderId(order.getOrderId());

        DeductStockRequest deductStockRequest = new DeductStockRequest();
        deductStockRequest.setProductId(request.getProductId());
        deductStockRequest.setQuantity(request.getQuantity());
        DeductStockResponse deductStockResponse = productCommonService.deductStock(deductStockRequest);

        return createOrderResponse;
    }
}

注意事项

  1. 业务模块之间是单向依赖,不能相互依赖。类似spring要求service不能相互引用。
  2. 启动类要加上各类bean的扫描
  3. A子模块调用B子模块,需要A在本模块的pom.xml内再引入B,后期如果微服务化,如基于rpc调用就无需引入,只用在service模块引入common模块即可
  4. web模块pom.xml增加启动类配置,去掉根项目pom.xml启动配置

源代码

gitee

下一篇:后端工程架构系列篇(二):微服务

基于阿里工具箱,dubbo、nacos、seata,全部为当前最新版本来演示

标签:架构,拆分,service,common,模块,import,mmyk,com
来源: https://www.cnblogs.com/penhuozhu/p/15757276.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有