后端工程产品、项目all in one 规范

工程改造

  1. 新建std模块(命名规范:[原工程名称]-std,例如pai-park-space : space-std),将原标准产品src(除启动类Application.java外)迁移至此模块。

    (std: standard简写,即代表标准产品)

  2. 新建application模块(命名规范:[原工程名称]-application,例如pai-park-space : space-application),迁移原标准产品启动类Application.java至此模块,保持原包路径

  3. 为避免后期项目过多从而导致首层级过于凌乱,新建客制化pom模块(命名规范:[原工程名称]-project,例如[pai-park-space] : space-project),用于存放客制化工程,修改pom文件,添加以下节点

    <packaging>pom</packaging>
  4. 在客制化pom模块下新建客制化模块(命名规范:[原工程名称]-[项目英文/简拼],例如[pai-park-space] + [海南港航]: space-hngh),用于存放客制化代码

风格1(标准单模块)

pai-park-space                         工程根目录(注意所有模块要带工程缩写做前缀,避免Maven .m2目录下Jar同名冲突)
├─space-application                    应用启动模块
│  └─src
│     └─main
│         └─java                       应用启动模块主类
├─space-project
│  └─contract-hngh                     客制化项目模块
│      └─src
│         └─main
│             ├─java                   客制化项目模块代码类
│             └─resources              客制化项目模块配置资源
├─space-std                            标准模块
│  └─src
│     └─main
│         ├─java                       标准模块代码类
│         └─resources                  标准模块配置资源
└─doc                                  文档资源目录

风格2(标准多模块)

pai-contract                           工程根目录(注意所有模块要带工程缩写做前缀,避免Maven .m2目录下Jar同名冲突)
├─contract-application                 应用启动模块
│  └─src
│     └─main
│         └─java                       应用启动模块主类
├─contract-project
│  └─contract-hngh                     客制化项目模块
│      └─src
│         └─main
│             ├─java                   客制化项目模块代码类
│             └─resources              客制化项目模块配置资源
├─contract-std                         标准模块
│  ├─contract-app                      标准子模块
│  │   └─src
│  │      └─main
│  │          ├─java                   标准子模块代码类
│  │          └─resources              标准子模块配置资源
│  ├─contract-base                     标准子模块
│  │   └─src
│  │      └─main
│  │          ├─java                   标准子模块代码类
│  │          └─resources              标准子模块配置资源
│  ├─contract-land                     标准子模块
│  │   └─src
│  │      └─main
│  │          ├─java                   标准子模块代码类
│  │          └─resources              标准子模块配置资源
│  ├─contract-lease                    标准子模块
│  │   └─src
│  │      └─main
│  │          ├─java                   标准子模块代码类
│  │          └─resources              标准子模块配置资源
│  ├─contract-property                 标准子模块
│  │   └─src
│  │      └─main
│  │          ├─java                   标准子模块代码类
│  │          └─resources              标准子模块配置资源
│  ├─contract-sale                      标准子模块
│  │   └─src
│  │      └─main
│  │          ├─java                   标准子模块代码类
│  │          └─resources              标准子模块配置资源
│  ├─contract-template                 标准子模块
│  │   └─src
│  │      └─main
│  │          ├─java                   标准子模块代码类
│  │          └─resources              标准子模块配置资源
│  └─contract-work-space               标准子模块
│      └─src
│         └─main
│             ├─java                   标准子模块代码类
│             └─resources              标准子模块配置资源
└─doc                                  文档资源目录
  1. application模块pom文件改造

    1. 添加profiles节点

      <profiles>
              <profile>
                  <id>std</id>
                  <activation><!--默认使用标准产品进行开发、打包-->
                      <activeByDefault>true</activeByDefault>
                  </activation>
                  <properties>
                      <product.path>space-std</product.path>
                  </properties>
                  <dependencies>
                      <dependency>
                          <groupId>cn.flyrise</groupId>
                          <artifactId>space-std</artifactId>
                          <version>${space.version}</version>
                      </dependency>
                  </dependencies>
              </profile>
              <profile>
                  <id>hngh</id>
                  <properties>
                      <product.path>space-hngh</product.path>
                  </properties>
                  <dependencies>
                      <dependency>
                          <groupId>cn.flyrise</groupId>
                          <artifactId>space-hngh</artifactId>
                          <version>${space.version}</version>
                      </dependency>
                  </dependencies>
              </profile>
          </profiles>

      默认std标准产品开发

      当进行非标准产品开发时,可在idea maven面板中进行勾选切换

    2. 添加build节点

            <build>
            <finalName>pai-park-space</finalName>
            <resources>
               <!-- 执行顺序为3,即使用客制化工程(space-xxx)的resources文件覆盖 【执行顺序2】的标准产品工程resources文件 -->
                <resource>
                    <directory>../space-project/${product.path}/src/main/resources</directory>
                    <includes>
                        <include>**/*</include>
                    </includes>
                </resource>
               <!-- 执行顺序为2,即使用标准产品工程(space-std)的resources文件覆盖【执行顺序1】的resources文件 -->
                <resource>
                    <directory>../space-std/src/main/resources</directory>
                    <includes>
                        <include>**/*</include>
                    </includes>
                </resource>
               <!-- 执行顺序为1,即先使用本工程(space-application)的resources文件 -->
                <resource>
                    <directory>src/main/resources</directory>
                    <includes>
                        <include>**/*</include>
                    </includes>
                </resource>
            </resources>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <executions>
                        <execution>
                            <goals>
                                <goal>repackage</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
  2. 工程根目录pom文件改造

    1. dependencyManagement,dependencies迁移到std模块pom文件中

    2. 去除build节点

  3. std模块pom改造,添加build节点

        <build>
            <resources>
                <resource>
                    <directory>src/main/resources</directory>
                    <excludes>
                        <exclude>mapper/**/*</exclude>
                    </excludes>
                </resource>
            </resources>
        </build>
  1. 客制化模块pom改造,

    1. 添加build节点

      <build>
              <resources>
                  <resource>
                      <directory>src/main/resources</directory>
                      <excludes>
                          <exclude>mapper/**/*</exclude>
                      </excludes>
                  </resource>
              </resources>
          </build>
    2. 引入std标准产品模块的依赖

              <dependency>
                  <groupId>cn.flyrise</groupId>
                  <artifactId>space-std</artifactId>
                  <version>${space.version}</version>
              </dependency>
  2. Dockerfile改造

ADD ./target/pai-park-space.jar ./

替换为

ADD ./space-application/target/pai-park-space.jar ./

all in one

实现Service类覆盖

  1. std模块添加BeanConfiguration.java 装载类,对于需要客制化的类进行兼容处理(多项目时会存在A需要客制、B不需要的情况)。

    (@ConditionalOnMissingBean直接在类声明中使用无效,具体参考说明)

    package cn.flyrise.pai.park.space.config;
    
    /**
     * bean自动装载配置类(取消配置bean的Service注解,用于客户化定制时更替换实现类)
     *
     * @author lhr
     * @date 2023/8/30 14:38
     */
    @Configuration
    public class BeanConfiguration {
    
        @Bean
        @ConditionalOnMissingBean(IRoomService.class)
        public IRoomService roomService() {
            return new RoomServiceImpl();
        }
    }
    
  2. 取消需要客制化Service类声明中的@Service注解

  3. 改动不大,如:只修改其中的某个方法(如方法为private,可改为protected),则可创建与父类同包名的继承类

    @Service("roomService")
    @Transactional(rollbackFor = RuntimeException.class)
    public class HnghRoomServiceImpl extends RoomServiceImpl {
        @Override
        public List<RoomVO> imports(MultipartFile file, String parkId) {
            // do somethings
        }
    }
  4. 如改动过大,也可直接整个类(同包、同类名)覆盖即可

VO、PO、DTO …等类覆盖

针对VO、PO、DTO …等类的增减字段、必填变更等,直接复制std模块vo类对象到客制化模块中相同包位置处进行调整即可

注意:

  1. 先将对应的类复制到客制化工程,提交到git后再进行改动,方便后期回溯改动
  2. service、mapper、dao.xml尽可能避免完整覆盖,完整覆盖会导致后期回溯变得异常困难,尽量使用上述【实现Service类覆盖】的方式进行覆盖

数据库相关

  1. 在客制化模块src/main/resources/meta/sql下新建文件,文件名在原有命名规范上,以_{客制化模块名称}.sql结尾

  2. 复制标准产品vo、po类到客制化相同位置,进行类覆盖字段增加

  3. 增加字段有特殊处理时应使用上述【Service类覆盖】的方式进行处理

    @Service("roomService")
    @Transactional(rollbackFor = RuntimeException.class)
    public class HnghRoomServiceImpl extends RoomServiceImpl {
        @Override
        public RoomVO add(RoomVO room) {
          if (CharSequenceUtil.isBlank(room.getNewField())) {
              throw new RequiredException(I18nUtil.get("new_field"));
          }
          return super.add(room);
        }
    }

mybatis mapper

  1. 新建对应mapper,命名规范为:客制化模块名称+原mapper名称,例:RoomMapper.java-> HngnRoomMapper.java。(用于区分namespace,如有完全新建功能也可置于此处)

  2. 新建*.xml,命名规范为:客制化模块名称+原xml名称,例:RoomDao.xml -> HngnRoomDao.xml

    <!--namespace指定为上述新建mapper-->
    <mapper namespace="cn.flyrise.pai.park.space.dao.HnghRoomMapper">
      ...
    </mapper>
  3. 继承

    <resultMap>提供了extends属性,可直接指向原resultMap实现继承

    <resultMap type="cn.flyrise.pai.park.space.model.po.RoomPO" id="RoomMap" extends="cn.flyrise.pai.park.space.dao.RoomMapper.RoomMap">
      <result property="isUse" column="is_use"/> <!--新增字段-->
      <result property="canArea" column="can_area"/><!--新增字段-->
      <result property="sharedArea" column="shared_area"/><!--新增字段-->
      <result property="useArea" column="use_area"/><!--新增字段-->
      <result property="isBreak" column="is_break"/><!--新增字段-->
    </resultMap>
  4. 覆盖

    <sql>、<select>、<insert>、<update>使用覆盖机制,将需要客制化的标签复制到新建的xml中进行调整即可

    注:<select>、<insert>、<update>中使用到的<resultMap>、<sql>需要一并复制,否则mybatis启动报错

  5. nacos.yml(复制标准工程至客制化工程后)添加mybatis配置(开发过程在客制化工程中复制标准工程bootstrap-dev.yml,并添加以下配置)

    mybatis:
      overrides:
         # key为标准产品xmlvalue为需覆盖的xml
        RoomDao.xml: HnghRoomDao.xml

    注意:如xml文件在mapper目录的下级目录,需要一并配置,例如:

    key出现特殊字符需要用”[]”包住,否则会丢失

    mybatis:
      overrides:
         "[enterprise/ClueEnterpriseMapper.xml]": enterprise/HnghClueEnterpriseMapper.xml

i18n

当部分字段、提示信息与标准产品不同时,可复制std模块下的i18n文件至客制化模块相同位置,按需求替换相应文字即可

common包

  1. 在工程【pai-fe】内新建【pai-fe-(项目名称)】,此处以hngh为例,即【pai-fe-hngh】模块,与VO类覆盖操作一致,复制需要更改的common包中对应的类到【pai-fe-hngh】模块中相同包位置,根据需求调整后进行覆盖替换。

  2. 引用包时,根据JVM 的类加载规则【先找到,先加载,后续忽略】的原则,在客制化模块(space-hngh)的pom文件中先引用【pai-fe-hngh】模块,再引用std标准模块,即可达到类覆盖的需求

        <dependencies>
            <dependency>
                <groupId>cn.flyrise</groupId>
                <artifactId>pai-fe-hngh</artifactId>
                <version>2.0.0.0-SNAPSHOT</version>
            </dependency>
            <dependency>
                <groupId>cn.flyrise</groupId>
                <artifactId>space-std</artifactId>
                <version>${space.version}</version>
            </dependency>
        </dependencies>

发布

pai image publish -n pai-park-space -r http://dev.flyrise.cn:8090/pai-park-space/pai-park-space.git -b dev-2.0.0.0 -P std

增加-P参数,用于指定打包的profile,如需发布客制版本,以hngh为例,则将 -P std 替换为 -P hngh进行发布即可

注意事项

idea切换profile的时候,有可能会导致不同工程模块文件冲突、或者会出现代码覆盖未达预期的情况,此时可考虑执行以下maven命令进行修复:

maven clean compile

后续

此方案进入实施阶段,可能会存在未考虑部分客制化实现的情况,需要大家集思广益、共同努力,希望大家多多思考,共同完善,使我们从繁乱的分支解放出来,最大程度达到即可在项目中完善标准产品,也能完美交付项目的理想状态。

文档更新时间: 2023-12-01 15:26   作者:陆鸿睿