如何用maven优化项目 | 七日打卡

1,651 阅读5分钟

引言

项目成立之初大多以效率为主,可能就拷贝了原始脚手架就开始了业务编码阶段.这种快速开发的模式在前期并没毛病,但是慢慢业务扩展开来,前期的技术债总是需要还的.各个服务间的jar包版本因为开发者的不同难以统一.统一的业务处理类可能也是各个服务各自存放,如果产品出现业务改动也需要一处处查找修改等等一系列问题都是让人头疼的.对整个项目的整改优化刻不容缓.下面总结一些我在优化过程中的一些经验.

思路

项目交由maven管理,这就为优化提供了便利.优化的思路主要以封装统一为主.以我们的一个项目为例,大致分为后台管理API服务前端api服务后端定时器服务后端消息服务.在未优化前各服务的jar包版本全是凭喜好各自能运行成功就OK,处理实体的公共类也是存放在各自的util包中,产品修改后,需要通过各个服务的负责人去修改.

统一

第一步统一jar包的版本 .防止服务联动时不会因为jar包问题导致错误.通过对maven的了解,可以把服务全都打包到一个父项目中,作为一个Multi-Module多模块项目.

---- shpping(maven父工程)
    |-- pom.xml (项目主pom文件)
    |   |-- 后台管理api
    |       |-- pom.xml (子pom)
    |   |-- 前端api
    |       |-- pom.xml (子pom)
    |   |-- 后端定时器
    |       |-- pom.xml (子pom)
    |   .......类推

此优化的重点在于项目主pom文件中的配置.需要兼顾各个子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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <packaging>pom</packaging> //标识该父功能的打包方式为pom
    <modules>
        //module的名称和你的子pom文件中的artifactId标签
        <module>mc-core</module>
        <module>mc-buy</module> 
        <module>mc-task</module>
        ......
    </modules>
    
    //以下是定义父功能的坐标
    <groupId>cn.mc</groupId>
    <artifactId>shopping</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>shopping</name>
    <description>项目简介</description>
    
    //统一定义下方dependency中的jar包版本
    <properties>
         <aliyun.oss.version>3.4.0</aliyun.oss.version>
         <spring.boot.version>2.2.6.RELEASE</spring.boot.version>
         ......
    </properties>
    
    //需要注意,在主pom文件的dependencies定义的jar会直接全部继承到子pom文件中,无需再次在子pom文件中声明.
    <dependencies>
      <!-- spring全家桶 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>
        ........
    </dependencies>
    
    //相对于dependencies,dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。
    //如果不在子项目中声明依赖便不会从父项目中继承下来.
    //只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项并且版本和引入方式都读取自主pom;
    //另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。
    <dependencyManagement>
        <dependencies>
            <!-- 阿里系 -->
            <dependency>
                <groupId>com.aliyun.oss</groupId>
                <artifactId>aliyun-sdk-oss</artifactId>
                <version>${aliyun.oss.version}</version>
            </dependency>
            ........
        </dependencies>
    </dependencyManagement>
</project>

说完主pom文件的一些定义,也来简单看看子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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    //指定主pom的坐标,使他们能够联动
    <parent>
        <artifactId>shopping</artifactId>
        <groupId>cn.mc</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>mc-buy</artifactId>
    <name>mc-buy</name>
    <description>api接口</description>
    
    <dependencies>
    //这里因为我们在主pom文件中定义了com.github.pagehelper的版本,所以在子pom文件中只需引入他的坐标,表示在主pom声明的此jar包在此处有引用.
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
        </dependency>
        .......
    </dependencies>

第二步统一配置文件 防止配置文件的不统一导致发版不一致.既然通过maven把项目整合在一起了,我们就再新建一个服务module专门用来存放公共配置.新建module的方法就不再赘述了.新建完后我们把他标记为maven项目.此时的项目结构为:

    ---- shpping(maven父工程)
    |-- pom.xml (项目主pom文件)
    |   |-- 后台管理api
    |       |-- pom.xml (子pom)
    ......
    |   |-- core核心包
    |       |src
    |           |java //存放统一的类
    |           |resources //存放统一的配置文件
    |               |application-core-dev
    |               |application-core-pro
    |               |application-core-test
    |       |-- pom.xml (子pom)

可以看到我们新建了一个core核心包,在resources包下我们可以新建配置文件,因为方便环境测试,我们新建三个环境的devprotest,分别对应本机、生产、测试.这时我们回到需要引入配置的module模块中,如后台管理api,只需要在yml文件中配置.

spring:
  profiles:
    include: core-dev

即可读取到core-dev的配置.同理可配置core-pro读取到application-core-pro的配置.在这个统一配置文件中可放置一些redis,mq等等服务都会用到可以统一的配置.

总结 通过这两处一致性的优化,可以使服务的jar包整齐划一,当项目中使用相同配置时,都是引入统一配置文件,也做到了配置文件统一.

封装

项目的公共代码封装也非常重要.为了统一配置文件我们新建了一个module-core核心包,这个包不仅可以帮我们统一配置,而且我们可以在他的java包中写上服务各自需要引用的处理类,当做一个核心jar包引入各自服务中.比如某些服务都需要一个日期处理类,这时候我们就在core包中 写入一个DateUtil类.在需要的服务中引入core jar

      <!-- core包-->
        <dependency>
            <groupId>cn.mc</groupId>
            <artifactId>mc-core</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

这时候我们就可以用DateUtil类了,当他需要修改时,我们也只需要修改后重新通过mvn install上载core包就可以更新各个引用core包的服务的该工具类了.是挺方便的,如果是以前的写法我们需要修改多个工具类,很容易出现遗漏的情况.

走过的坑

Multi-Module多模块项目是非常好用的一种管理方式,我这边大概总结两个遇到的坑.

  • 如果子模块新增类或者修改类,需要重新install该模块,引入他的模块才可以接收到该jar的更新,包括配置文件也是一样.虽然在本地编译是没有问题的,但是如果不install的话,打包成jar是不会生效的.
  • 如果主pom文件增加jar文件,需要install整个父项目,不然子项目是找不到该jar包的.

总结

在项目业务多的时候,应该考虑各种功能统一的方式才能让开发的精力能放在业务实现上,不然一个小小的改动就会牵动很多遗留bug,所以如果你们公司的项目也存在这个问题,还是建议今早改造长痛不如短痛.