技能一 optional true
我们可以使用 Maven 的optional 为true这个选项。使用这个选项有什么好处呢?
- 举个例子,我们最熟悉的数据库,如果我们需要开发一个统一的框架,这个时候我们可能会依赖MYSQL,Oracle,PG等,我们需要将这些相关的依赖都依赖到我们这个框架中。但是客户端它在使用的时候不会全部都使用。这个时候optional 为true就登场了,它能够保证我们的框架正常编译,同时不传递给依赖方。
- 节约空间,由于我们不传递依赖,自然整个项目的体积就会减少。
举个例子,我们需要再data模块这整合数据相关的操作,就可以使用这样的方式:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<optional>true</optional>
</dependency>
技能二 插件flatten-maven-plugin 的使用
好首先咋们把这个配置放到这里,那么这个插件有什么用呢?那就是统一版本
<properties>
<revision>0.0.1-SNAPSHOT-flatten</revision>
<maven-flatten-plugin.version>1.2.5</maven-flatten-plugin.version>
</properties>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
<version>${maven-flatten-plugin.version}</version>
<configuration>
<updatePomFile>true</updatePomFile>
<flattenMode>resolveCiFriendliesOnly</flattenMode>
</configuration>
<executions>
<execution>
<id>flatten</id>
<phase>process-resources</phase>
<goals>
<goal>flatten</goal>
</goals>
</execution>
<execution>
<id>flatten.clean</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
好我们在properties定义了revision这个属性,然后我们在当前pom.xml 使用,这个模块是父工程:
<groupId>com.acme</groupId>
<artifactId>biz-project</artifactId>
<version>${revision}</version>
<packaging>pom</packaging>
在子模块:
<parent>
<groupId>com.acme</groupId>
<artifactId>biz-project</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
看到了木有,我们只需要修改一个地方,所有的版本都统一了。
而且你可以在pom引用,比如我们需要再core模块引用data模块,这样子这个版本就不会出现错乱的情况啦:
技能三 依赖仲裁
<dependencyManagement>
在这个里面放在前面的会被maven先仲裁,也就是说在这个标签里面位置顺序会影响依赖仲裁,越靠前越优先。
</dependencyManagement>
案例一
例子:
<dependencyManagement>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.2</version>
</dependency>
</dependencyManagement>
这个时候虽然2.7.2依赖于4.0.1,但是maven会仲裁为4.0。
案例二
这里我使用的是 <dubbo.version>2.7.8</dubbo.version>
dubbo 也引用了Spring FrameWork,如果我们将Dubbo放在前面看到了木有,用的就是2.7.8里面的依赖。
行,咱交换一个顺序,看到了木有这个时候就是依赖的spirngboot2.7.2中的Spring FrameWork:
技能四 BOM
pom 的继承也是单继承,那如果这个时候我们父工程比如继承了apache,但是我们又想继承Spring Boot怎么办呢?
我们可以采用BOM的方式,这样的话不是继承而是聚合模块,效果和Parent是一样的。
<parent>
<groupId>org.apache</groupId>
<artifactId>apache</artifactId>
<version>23</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-bom</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
技能五
这个网站可以查看依赖版本的范围
https://raw.githubusercontent.com/spring-io/start.spring.io/main/start-site/src/main/resources/application.yml
比如以SpringCloud为例:
技能六 打包的时候排除依赖
当然我们可以采用optional为true的方式避免依赖不必要的依赖,那如果你是用的别人的包,你控制不了,那么没有关系,这个时候在打包的时候你还可以通过插件进行排除,例子如下:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<mainClass>com.acme.biz.web.BizWebApplication</mainClass>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>
技能七 统一提供
我们也可以把要向外暴露的模块聚合在一起,统一提供比如这个模块就叫biz-dependencies:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.acme</groupId>
<artifactId>biz-api</artifactId>
<version>${revision}</version>
</dependency>
</dependencies>
</dependencyManagement>
这样子别人就可以使用我们的BOM啦。
至于模块化命令规则和包名规则可以参照参考资料的连接。
参考资料:
https://github.com/mercyblitz/java-training-camp/tree/main/stage-1/src/biz-project