非Java的同学,快速时间实践了下Maven的模块安装过程
1. Java环境部署
1.1. Java开发与运行环境
Java介于编译语言与解释语言之间,通过编译器将Java代码编译成"java字节码"(抽象了CPU指令)在JVM虚拟机上运行,以实现跨平台的能力;
JVM虚拟机兼容性好,支持低版本字节码在高版本JVM上运行。
- 开发标准
- Java ME: Java SE的Mini版,不与JSE版本兼容
- Java SE:标准版,包括Java标准库、语言本身
- Java EE:企业版,增加大量API和库,方便Web开发,JEE使用的JVM与JSE兼容(Spring框架),Java 其他应用:安卓开发、Hadoop、Spark、Flink等
- 开发与运行环境
- JDK(Java Development Kit): Java开发工具包,提供JRE(Java Running Env)环境,包括
- JRE(Java Runtime Environment): Java运行环境
- 2020/09 Java版本是Java15
- BIN执行程序
- java: 启动JVM,运行Java字节码
- javac: Java字节码编译器,将
.java
源文件编译成.class
结尾的字节码 - jar: 打包程序,将多个
.class
字节码文件,打成jar包程序 - javadoc:从代码生成文档
- jdb: Java调试器,开发阶段运行调试
1.2. JDK下载和配置
- JDK下载: https://www.oracle.com/java/technologies/javase-jdk15-downloads.html
- 配置
~/.zshrc
1
2
| export JAVA_HOME=`/usr/libexec/java_home -v 15`
export PATH=$JAVA_HOME/bin:$PATH
|
2. JAVA程序
2.1. HelloWorld
- javac编译Hello.java => Hello.class(java字节码)
java Hello
,寻找Hello.class
=> 启动JVM,执行Hello.class
;另外,从java11其,支持java运行Hello.java,即java Hello.Hello
1
2
3
4
5
6
7
8
| // Hello.java文件,与定义类名一致,则java Hello可以执行
// 从Java11起,文件名如果不一致,则需要指定Java源文件全称, Hello.java,即java Hello.java
public class Hello {
// java固定入口程序
public static void main(String[] args) {
System.out.println("Hello, world!");
}
}
|
2.2. Java语法
- 基本语法
- 变量类型(整、浮、布、字符+串、数组)
- 流程控制(IO、IF、swith、while、do while、for、break、continue)
- 数组操作(多维、遍历、排序)
- OOP
- 构造方法(与类名相关)
- 方法
- 可见范围(私有、保护、公共)
- 继承:
- 超类、父类、基类;
- 子类、扩展类。
- Java仅支持单集成。Object特殊类。
- final阻止继承。
- 集成向下转换(父转子OK,子转父Err)。
- instanceof判断实例类型
- 重载(Overload):方法名称一样,但参数不一样。重载的返回值类型通常都是相同的。
- int indexOf(int ch):根据字符的Unicode码查找;
- int indexOf(String str):根据字符串查找;
- 覆写(Override):方法签名一致,加上
@Override
可以让编译器帮助检查是否进行了正确的覆写(理解为编译器校对) - 多态:类似接口,或者基类作为参数,可以传入不同子类,产生不同效果
- 接口:接口做抽象,多态发挥能力。interface
- 抽象:
- 抽象方法:
public abstract void run();
- 抽象类:`abstract class Person {},抽象方法,有抽象方法的类就是抽象类
- 静态字段与静态方法:
static字段
: 也叫实例字段,所有实例共享实例字段空间static方法
: 无需实例类,就可以调用类方法
2.3. package包
- 通过package包解决命名冲突,比如
package a
,多层包用点号分隔,包没有父子关系:package a.b.c
- 通常包放在src目录内;在同一个包下的,文件共用该包作用域,除此外还受可见性修饰词控制(
public、protect、private
)
import导入包:
直接通过全路径包名+类名+方法调用,比如a.b.ClassX.Func()
,a.b
包下的ClassX类的Func()
方法,问题是会导致非常多冗余
- 通过import导入包,再通过类名+方法名调用
import a.b.ClassX
,再调用Func()
- 支持
*
批量导入,导入所有的class
,不包括子class`
- 包名推荐倒置域名方式,Eg由大到小
com.tencent.ketang.sample
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| // 包路径
com
├── ali
│ ├── AliHello.java
│ └── Hello.java
├── tencent
│ └── Hello.java
└── util
└── UtilHello.java
// 编译所有java文件
$ javac com/ali/* com/tencent/*
// 通过import导入外部包
package com.util;
import com.ali.AliHello;
import com.tencent.*;
public class UtilHello {
public static void main(String[] args) {
AliHello.SayHello();
Hello.main(args);
}
}
|
2.4. classpath
classpath
是JVM用到的一个字节码class文件path路径变量,即一组目录的集合,用来指示JVM如何搜索class字节码文件文件。
classpath设置
- 通过环境变量设置(不推荐):
/usr/shared:/usr/local/bin:PathA:PathB
- 通过JVM启动设置(推荐):
-classpath
,或简写-cp
示例:java -cp /usr/shared:/usr/local/bin:PathA:PathB
默认classpath
为当前目录,若package包名com.example
和目录名com > example > Hello.java
约定一致,只可以直接使用编译,java -cp . com.example.Hello
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| $ tree ./com
./com
├── ali
│ ├── Hello.class
│ └── Hello.java // package com.ali;
└── tencent
├── Hello.class
└── Hello.java // package com.tencent;
// 编译java代码
$ javac com/ali/* com/tencent/*
// 运行java字节码程序,甚至可以省略-cp指定,因为默认cp就是当前目录
$ java -cp . com.tencent.Hello
$ java com.ali.Hello
learn.Hello, QQ!
|
2.5. jar包
- jar包实际上就是一个zip格式的压缩文件,可以通过zip压缩+重命名得到jar包,但需要注意
jar
包目录结构 - jar不管class之间的依赖,
Java9
开始主要解决依赖问题,若依赖有问题通常遇到ClassNotFoundException
错误 - 可以Maven便创建和管理jar包
zip打包jar,并运行jar包
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| // 目录
com
├── ali
│ ├── Hello.class
│ └── Hello.java
└── tencent
├── Hello.class
└── Hello.java
// 通过zip打包jar文件
$ zip -r com.zip ./com
$ mv ./com.zip ./com.jar
// 运行jar包,可以将./com.jar拷贝到任何地方,然后执行下面命令
$ java -cp . com.ali.Hello
learn.Hello, ALIBABA!
$ java -cp ./com.jar com.ali.Hello
learn.Hello, ALIBABA!
$ java com.ali.Hello
learn.Hello, ALIBABA!
|
利用jar命令打包
- 创建:
jar --carete --file xx.jar ...
,简写成jar -c -f xx.jar ...
,不支持连写,即-cf xx.jar
报错 - 更新:
jar --update --file xx.jar ...
,简写成jar -u -f xx.jar ...
被打包内容支持:
- 通过
.class
结尾的字节码文件 - 通过
manifest
申明的文件清单,通过-C dir
指定包含class文件目录 - 通过
Module
模块方式申明,通过-C dir
指定包含class文件目录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| // 创建包含两个类文件的名为 classes.jar 的档案:
jar --create --file classes.jar Foo.class Bar.class
# 使用现有的清单创建档案, 其中包含 foo/ 中的所有文件:
jar --create --file classes.jar --manifest mymanifest -C foo/ .
# 创建模块化 jar 档案, 其中模块描述符位于
# classes/module-info.class:
jar --create --file foo.jar --main-class com.foo.Main --module-version 1.0
-C foo/ classes resources
# 将现有的非模块化 jar 更新为模块化 jar:
jar --update --file foo.jar --main-class com.foo.Main --module-version 1.0
-C foo/ module-info.class
# 创建包含多个发行版的 jar, 并将一些文件放在 META-INF/versions/9 目录中:
jar --create --file mr.jar -C foo classes --release 9 -C foo9 classes
|
2.6. Module模块
jar是class的封装,jmod是用于解决模块依赖和拆分问题,jre是应用运行时环境,直接可执行,可以通过jlink链接指定mod降低jre生成目录的大小
Java Module背景
从java9开始引入模块,.class
JVM可见最小执行文件,jar
将离散.class
管理起来,如果有多个jar依赖包,需要将多个jar包引入后执行:java -cp a.jar:b.jar:c.jar:com.tencent.sample.jar com.tencent.sample.Main
java9开始将原有的Java标准库由rt.jar
单个jar包分拆成了几十个以.jmod
结尾的模块,放在$JAVA_HOME/jmods
目录下,
模块名就是文件名,比如模块java.base
对应的文件就是java.base.jmod
,所有模块都依赖java.base
根模块。
与把一堆class字节码文件打包jar包相比,模块在此基础上还解决了模块依赖关系问题
1
2
3
4
5
6
7
8
| $ ls -l $JAVA_HOME/jmods
total 154512
-rw-r--r-- 1 root wheel 17874844 9 15 22:11 java.base.jmod
-rw-r--r-- 1 root wheel 124407 9 15 22:11 java.compiler.jmod
-rw-r--r-- 1 root wheel 51506 9 15 22:11 java.datatransfer.jmod
-rw-r--r-- 1 root wheel 13349032 9 15 22:11 java.desktop.jmod
-rw-r--r-- 1 root wheel 40729 9 15 22:11 java.instrument.jmod
...
|
如何编写模块
- 初始化模块目录结构,创建
bin
、src
两个目录,src内放java包源码 - 编写java模块源码
- 编写
module-info.java
文件,指明源码模块依赖 - 编译,会在bin下生产了class后缀的字节码文件,以及多出一个
module-info.class
文件 - 运行,通过
java -cp
指定classpath,指定入口包的类名(com.ali.Hello
或com.tencent.Hello
) - 打包模块目录为单个
jar
文件,同时申明入口类,jar -c -f ali-hello.jar -e com.ali.Hello -C ./bin .
- 运行,通过
jar -jar
运行jar包 - 创建模块,同
jmod create --class-path ali-hello.jar ali-hello.jmod
生成模块文件
注意:java相关运行命令参数有的不支持简写,比如java -cp
与java --class-path
一致,但jmod
仅支持--class-path
,不支持简写的-cp
2.6.1. 初始化模块目录结构,创建bin、src
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
| // 初始化模块目录结构
$ tree oop-base
oop-base
├── bin
└── src
├── com
│ ├── ali
│ │ ├── AliHello.java
│ │ └── Hello.java
│ └── tencent
│ └── Hello.java
└── module-info.java
// 1.1 com.ali.AliHello.java
package com.ali;
public class AliHello {
public static void SayHello() {
System.out.println("Hey, Ali");
}
}
// 1.2 com.ali.Hello.java (入口文件)
package com.ali;
public class Hello {
public static void main(String[] args) {
AliHello.SayHello();
}
}
// 2 com.tencent.Hello (入口文件)
package com.tencent;
public class Hello {
public static void main(String[] args) {
System.out.println("oop-base module, Hello, QQ!");
}
}
// module-info.java内容,假定java包依赖xml、logging模块内容,则可以编译如下
module oop.base {
requires java.base;
requires java.xml;
requires java.logging;
}
// 模块内的类遵循public,protect,private可见性约束,但如果想把oop.base模块内某些类导出,则需要通过expose导出包
module oop.base {
// 假定需要导出com.ali包下所有内容给到其他模块使用
exports com.ali;
requires java.base;
requires java.xml;
requires java.logging;
}
|
2.6.2. 编译java源码包
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| // 编译,指定module-info.java位置、class源码内容,-d指定编译后字节码文件存储位置
$ javac -d bin src/module-info.java src/com/ali/* src/com/tencent/*
// 编译后,看到bin下生产了class后缀的字节码文件,以及多出一个module-info.class文件
$ tree oop-base
oop-base
├── bin
│ ├── com
│ │ ├── ali
│ │ │ ├── AliHello.class
│ │ │ └── Hello.class
│ │ └── tencent
│ │ └── Hello.class
│ └── module-info.class
├── oop-base.iml
└── src
├── com
│ ├── ali
│ │ ├── AliHello.java
│ │ └── Hello.java
│ └── tencent
│ └── Hello.java
└── module-info.java
|
2.6.3. 基于classpath目录运行
1
2
3
4
5
6
| // 指定cp目录,运行一把
$ cd oop-base
$ java -cp ./bin com.ali.Hello
Hey, Ali
$ java -cp ./bin com.tencent.Hello
oop-base module, Hello, QQ!
|
2.6.4. 将bin目录下class字节码打包成jar,并运行jar包
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| // 将bin目录下class字节码打包成jar,需要指定--main-class
$ jar --create --file ali-hello.jar --main-class com.ali.Hello -C bin/ .
$ jar -c -f tencent-hello.jar -e com.tencent.Hello -C ./bin .
// 指定jar文件,运行一把(因为ali-hello.jar和tencent-hello.jar都有彼此的入口类,所以jar包可以相互执行)
$ java -cp ./ali-hello.jar com.ali.Hello
Hey, Ali
$ java -cp ./ali-hello.jar com.tencent.Hello
oop-base module, Hello, QQ!
$ java -cp ./tencent-hello.jar com.ali.Hello
Hey, Ali
$ java -cp ./tencent-hello.jar com.tencent.Hello
oop-base module, Hello, QQ!
// 通过-jar指定jar文件,默认启动入口程序
$ java -jar ali-hello.jar
Hey, Ali
$ java -jar tencent-hello.jar
oop-base module, Hello, QQ!
// 因为jar文件已是模块化了的,因此可以通过--module运行已被jar打包的模块
$ java --module-path tencent-hello.jar --module oop.base
oop-base module, Hello, QQ!
|
2.6.5. 通过jmod打包
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| // 打包成jmod
$ jmod create --class-path ali-hello.jar ali-hello.jmod
// jmod明细信息
$ jmod describe ali-hello.jmod
oop.base
requires java.base
requires java.logging
requires java.xml
contains com.ali
contains com.tencent
main-class com.ali.Hello
// jmod包含内容
$ jmod list ali-hello.jmod
classes/module-info.class
classes/META-INF/MANIFEST.MF
classes/com/tencent/Hello.class
classes/com/ali/AliHello.class
classes/com/ali/Hello.class
|
2.6.6. 通过jlink链接依赖mod,并打包生成JRE目录
之前说到rt.jar
基本jar包过大,过去运行Java应用,必须下载完整的JRE运行时环境(非常大100M),可以通过jlink
指定我们应用的模块依赖,给JRE内容瘦身,瘦身完后,只需要把Jre目录打包发给对方,对方直接运行即可;
1
2
3
4
5
| $ jlink --module-path ./ali-hello.jmod --add-modules java.base,java.xml,oop.base --output jre/
// 生成后,可以直接执行JRE下的java程序
$ ./jre/bin/java --module oop.base
Hey, Ali
|
2.7. 类之间嵌入
- 类之间关系:
- Java的内部类可分为Inner Class、Anonymous Class和Static Nested Class三种
3. Maven
- 下载安装Maven依赖包管理工具
- 在
~/.m2
配置目录,配置Maven镜像仓库,加速依赖包下载速度 - 初始化Maven项目结构,配置
pom.xml
依赖包管理文件 - 进入
pom.xml
配置目录,执行相关mvn命令:清理、编译、测试、打包等
3.1. Maven简介
Maven是一个Java项目构建工具,它可以定义项目结构、项目依赖,并使用统一的方式进行自动化构建Java应用。
通常一个Java项目需要的东西:
- 确认依赖包
- 确认目录结构(
src
放源码、resource
放配置、bin
放编译生成的.class字节码文件
) - 确认编译环境
- 编写流水线编译Shell脚本,自动化构建
Maven就是确认上面这套流程的工具:
- 提供了一套标准化的项目结构;
- 提供了一套标准化的构建流程(编译,测试,打包,发布……);
- 提供了一套依赖管理机制。
Maven在Mac上的安装
1
2
3
4
5
6
7
8
9
| // 安装
brew install maven
// Maven环境变量配置
M2_HOME=/path/to/maven-3.6.x
PATH=$PATH:$M2_HOME/bin
// 版本
mvn -version
|
3.2. Maven项目结构
1
2
3
4
5
6
7
8
9
10
| a-maven-project
├── pom.xml // 项目描述文件
├── src // 源码
│ ├── main
│ │ ├── java // Java源码
│ │ └── resources // 资源目录
│ └── test // 测试代码
│ ├── java
│ └── resources
└── target // 编译、打包生成文件存储
|
3.3. pom.xml配置文件
- Maven使用
pom.xml
定义项目内容,并使用预设的目录结构; - Maven中声明一个依赖项可以自动下载并导入classpath;
- Maven使用groupId,artifactId和version唯一确认一个依赖,Maven从中央镜像仓库下载依赖,一旦拉取就生成本地缓存(
用户主目录.m2
)- groupId:属于组织的名称;
- artifactId:该jar包自身的名称;
- version:该jar包的版本,以
-SNAPSHOT
结尾的版本被视为开发版,每次都会从Maven镜像源下载
- 针对依赖包还有子依赖包的情况,Maven会一并将其加入到我们的项目依赖,并将其导入到我们的classpath中,不需要去管项目依赖包的子依赖包情况
- 如果要引入一个第三方库,但不清楚该依赖库的
GroupID
、artifactId
、version
,可以通过 search.maven.org 域名检索
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| // 配置文件实例
<project ...>
<modelVersion>4.0.0</modelVersion>
// 类似Java包名,通常组织ID
<groupId>com.ali</groupId>
// 类似Java类目
<artifactId>hello</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<properties>
...
</properties>
// 依赖包comons-logging情况
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
</project>
|
包之间的依赖范围scope关系
- compile: 编译时候需要(默认)
- test: 编译测试时候需要
- runtime:编译无需,但运行时刻需要
- provided:编译需要,运行时候由JDK提供
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| // 测试依赖
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.3.2</version>
<scope>test</scope>
</dependency>
// 运行时依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
<scope>runtime</scope>
</dependency>
// 编译依赖,运行无需要依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
|
3.4. Maven通过镜像仓库下载jar依赖
申明了项目jar包依赖,并会从中央仓库(repo1.maven.org
)下载依赖包(第三方库需要将jar以及其依赖上传上去),同时Maven会缓存下载的jar包到~/.m2
目录下,避免每次编译过程都需要从中央仓库拉取;
仓库类型:
- 中央仓库:repo1.maven.org,可以通过镜像仓库缓存中央仓库的模块内容,实现下依赖包载加速;
- 私有仓库:比如公司内部使用库放在自己部署的私有仓库中,需要在
~/.m2/settings.xml
配置; - 本地仓库:通过将本地编译的class内容发布在本地,方便其他本地仓库的引用,这块不建议使用,容易导致版本不一致问题;
除了通过中央仓库下载依赖jar包,还可以通过镜像拉取,比如阿里云Maven镜像资源,可以通过在~/.m2
中创建一个setting.xml
,配置镜像仓库:
1
2
3
4
5
6
7
8
9
10
11
| <settings>
<mirrors>
<mirror>
<id>aliyun</id>
<name>aliyun</name>
<mirrorOf>central</mirrorOf>
<!-- 国内推荐阿里云的Maven镜像 -->
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>
</mirrors>
</settings>
|
3.5. 构建项目
Maven支持标准化结构,还有一套标准化构建流程,通过一系列阶段(Phase)完成软件构建的生命周期(LifeCycle),Phase阶段包含校验、初始化、source、resources、编译、测试、构建包、集成测试、安装、部署等一些内容,每个Phase步骤,又会包含多个Goal执行具体的细节内容。
常用maven操作:
- 编译
mvn compile
,执行Maven默认流程,一直运行到compile
步骤
- 打包
mvn package
: 执行Maven默认流程,一直运行到package
步骤
- 清理:
mvn clean
:清理所有生成的class和jarmvn clean compile
,先清理,再执行到compile;mvn clean test
,先清理,再compile,最后执行test;mvn clean package
: 先清理,再执行到package
另外一点,Maven实际是通过plugin
机制来执行Phase的,比如compiler:compile
是一个编译节点的Goal,Maven实际上只是去调用这个Goal,具体怎么做还是依赖一插件实现
3.6. 多模块情况
我们可以将一个大项目拆分成若干小模块,以降低软件复杂度;假定A、B模块都有类似的依赖,可以独立抽离出一个parent pom
来负责存储公共依赖(注意公共parent的pom.xml的packaging字段为pom
,而非jar
);在子模块pom.xml
可以通过<parent>
引入parent模块内容;同时根pom.xml
可以通过modules
包括几个模块,方便Maven统一清理编译等操作:
分多模块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| // 目录划分
multiple-project
├── pom.xml
├── parent
│ └── pom.xml
├── module-a
│ ├── pom.xml
│ └── src
├── module-b
│ ├── pom.xml
│ └── src
└── module-c
├── pom.xml
└── src
|
parent/pom.xml
1
2
3
4
5
6
7
8
9
| <project ...>
...
<groupId>com.itranswarp.learnjava</groupId>
<artifactId>parent</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<name>parent</name>
...公共依赖
</project>
|
module-a/pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| <project ...>
<!-- // 声明parent部分 -->
<parent>
<groupId>com.itranswarp.learnjava</groupId>
<artifactId>parent</artifactId>
<version>1.0</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>
<!-- // 模块a声明 -->
<artifactId>module-a</artifactId>
<packaging>jar</packaging>
<name>module-a</name>
...A独立依赖
</project>
|
根pom.xml
囊括所有pom.xml,执行mvn clean package时,一起编译4个模块内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| <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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.itranswarp.learnjava</groupId>
<artifactId>build</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<name>build</name>
<modules>
<module>parent</module>
<module>module-a</module>
<module>module-b</module>
<module>module-c</module>
</modules>
</project>
|
3.7. 项目使用指定版本Maven - mvnw(Maven Wrapper)
通常所有项目使用统一全局的Maven,但某些情况某些项目依赖特定版本Maven,这类情况可以通过mvnw - Maven Wrapper
解决,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| // 安装mvnw,通过mvn指定安装0.7.6最新版Maven-Wrapper,同时指定当前项目版本的Maven为`3.3.3`
mvn -N io.takari:maven:0.7.6:wrapper -Dmaven=3.3.3
// 可以通过-X查看错误调试信息
mvn -X io.takari:maven:0.7.6:wrapper -Dmaven=3.3.3
// 查看
my-project
├── .mvn
│ └── wrapper
│ ├── MavenWrapperDownloader.java
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
├── main
└── test
|
安装完后,需要把生成的.mvn
、mvnw
、mvnw.cmd
一并提交到仓库,方便其他同学拉取后,使用同样版本Maven拉取依赖:
1
2
| // 通过mvnw拉取
./mvnw clean package
|
3.8. 推送模块库文件到Maven仓库
以单独静态文件发布
- 规范:
groupId:artifactId:verion
,举例commons-math3-3.6.1.pom
:
推送步骤:
- 初始化Maven项目目录:
pox.xml
,src
,target
- 仓库编写
pom.xml
,依次填入源软件包仓库URL,定义Build源码和文档插件,仓库描述,依赖情况等信息 - 执行
mvn clean package deploy
进行发布仓库
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
| // pom参考
<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>组织ID</groupId>
<artifactId>包ID</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>15</maven.compiler.source>
<maven.compiler.target>15</maven.compiler.target>
<java.version>15</java.version>
</properties>
<!-- 仓库描述 -->
<repositories>
<repository>
<id>仓库ID</id>
<name>仓库名称</name>
<url>{仓库地址}</url>
</repository>
</repositories>
<dependencies>
<dependency>
...
</dependency>
</dependencies>
</project>
|