一 Maven介绍
Maven是一个项目管理工具,它包含了一个项目对象模型 (Project Object Model),一组标准集合,一个项目生命周期(ProjectLifecycle),一个依赖管理系统(Dependency Management System),和用来运行定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑。 当你使用Maven的时候,你用一个明确定义的项目对象模型来描述你的项目,然后 Maven 可以应用横切的逻辑,这些逻辑来自一组共享的(或者自定义的)插件。
从Apache maven网站上下载maven并安装,maven目录下/conf/setting.xml中定义的是全局配置信息,里面包含了项目公用的localRepository(私有仓库)位置,pluginGroups,proxies,servers,profiles等属性,xml里文档注释很详细,具体含义可以参见文档,比较重要的有localRepository,profiles等,建议将配置文件放入~/.m2/settings.xml,实现用户范围控制。
<!-- localRepository | The path to the local repository maven will use to store artifacts. | | Default: ~/.m2/repository <localRepository>/path/to/local/repo</localRepository> --> <localRepository>d:/rr</localRepository>
pom是描述项目对象模型的,每个maven项目必须包含pom.xml,一个简单的pom中包含的信息有:坐标信息、依赖管理、属性值等。
超级POM定义了一组被所有项目共享的默认设置。它是Maven安装的一部分,可在/usr/local/maven/lib中的maven-xxx.jar文件中找到。如果你看一下这个JAR文件,你会看到在包org.apache.maven.project下看到一个名为pom-4.0.0.xml的文件。从这个文件可以看到默认的属性值和默认执行的插件。
二 Maven 变量
1 Maven提供了三个隐式的变量:
env
暴露了你操作系统或者shell的环境变量
project
暴露了POM。你可以使用点标记(.)的路径来引用POM元素的值${project.artifactId},你可能在老的构建中看到使用${pom.xxx}或者仅仅${xxx}来引用POM属性。这些方法已被弃用,我们只应该使用${project.xxx}。所有pom中的元素都可以用 project. 前缀进行引用,以下是部分常用的
${project.build.directory } results in the path to your "target" dir, this is the same as ${pom.project.build.directory }
${project.build. outputD irectory } results in the path to your "target/classes" dir
${project.name } refers to the name of the project.
${project.version } refers to the version of the project.
${project.build.finalName } refers to the final name of the file created when the built project is packaged
settings
暴露了Maven settings信息如:
${settings.offline}会引用~/.m2/settings.xml文件中offline元素的值
${settings.localRepository } refers to the path of the user's local repository.
2 内置属性
主要有两个常用内置属性:
${basedir}表示项目根目录,即包含pom.xml文件的目录
${version}表示项目版本
3 Java系统属性
所有Java系统属性都可以使用Maven属性引用,例如${user.home}指向了用户目录。
可以通过命令行mvn help:system查看所有的Java系统属性
4 环境变量属性
所有环境变量都可以使用以env.开头的Maven属性引用。例如${env.JAVA_HOME}指代了JAVA_HOME环境变量的值。也可以通过命令行mvn help:system查看所有环境变量。
系统的环境变量通过 env. 前缀引用,如:
${env.M2_HOME } returns the Maven2 installation path.
${java.home } specifies the path to the current JRE_HOME environment use with relative paths to get for example:
<jvm>${java.home}../bin/java.exe</jvm>
5 使用系统属性
Java系统属性,所有可以通过java.lang.System中getProperties()方法访问的属性都被暴露成POM属性。一些系统属性的例子是:hudson,/home/hudson,/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/jre,和Linux。一个完整的系统属性列表可以在java.lang.System类的Javadoc中找到。
6 自定义属性
通过pom.xml或者settings.xml中的properties元素设置自己的属性,如:
<project> ... <properties> <foo>bar</foo> </properties> ... </project>
7 上级工程的变量
上级工程的pom中的变量用前缀 ${project.parent } 引用. 上级工程的版本也可以这样引用: ${parent.version }.
二 Maven 依赖管理
Maven一个强大的功能是它能够帮助管理项目的依赖,一个项目对其他项目或包的依赖范围分为如下几种:
test | 当你只有在测试的时候才引用类库的时候,你就要使用测试范围依赖 |
compile | 编译范围(compile)依赖。(默认)如果你的项目在编译,测试,和运行中都依赖于一个类库 |
provided | 当你的开发过程只有在编译和测试时需要一个类库,而该类库在运行的时候由容器提供,那么你就需要使用已提供范围的依赖,例如,如果你开发了一个web应用,你可能在编译classpath中需要可用的Servlet API来编译一个servlet,但是你不会想要在打包好的WAR中包含这个Servlet API;这个Servlet API JAR由你的应用服务器或者servlet容器提供 |
runtime | runtime依赖在运行和测试系统的时候需要,但在编译的时候不需要。比如,你可能在编译的时候只需要JDBC API JAR,而只有在运行的时候才需要JDBC驱动实现。 |
system | system范围依赖与provided类似,但是你必须显式的提供一个对于本地系统中JAR文件的路径。这么做是为了允许基于本地对象编译,而这些对象是系统类库的一部分。这样的构件应该是一直可用的,Maven也不会在仓库中去寻找它。如果你将一个依赖范围设置成系统范围,你必须同时提供一个systemPath元素。注意该范围是不推荐使用的(你应该一直尽量去从公共或定制的Maven仓库中引用依赖)。 |
可选依赖:
<dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> <version>1.4.1</version> <optional>true</optional> </dependency>
在你将这些依赖声明为可选之后,你就需要在依赖于my-project的项目中显式的引用对应的依赖。例如,如果你正编写一个应用,它依赖于my-project,并且想要使用EHCache实现,你就需要在你项目添加如下的dependency元素,在理想的世界中,你不需要使用可选依赖。你可以将EHCache相关的代码放到yproject-ehcache子模块中,将SwarmCache相关的代码放到my-project-swarmcache子模块中,而非创建一个带有一系列可选依赖的大项目。
依赖界限
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>[3.8,4.0)</version> <scope>test</scope> </dependency>
传递依赖
范围如何影响传递性依赖,行表示直接依赖,行与列的交叉就是为某个传递性依赖指定的范围。表中的空格意思是该传递性依赖被忽略)
compile | provided | runtime | test | |
compile | compile | - | runtime | - |
provided | provided | provided | provided | - |
runtime | runtime | - | runtime | - |
test | test | - | test | - |
如果project-a包含一个对于project-b的测试范围依赖,后者包含一个对于project-c的编译范围依赖。project-c将会是project-a的测试范围传递性依赖。
排除一个传递性依赖
<dependency> <groupId>org.sonatype.mavenbook</groupId> <artifactId>project-a</artifactId> <version>1.0</version> <exclusions> <exclusion> <groupId>org.sonatype.mavenbook</groupId> <artifactId>project-b</artifactId> </exclusion> </exclusions> </dependency>
排除并替换一个传递性依赖
<dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate</artifactId> <version>3.2.5.ga</version> <exclusions> <exclusion> <groupId>javax.transaction</groupId> <artifactId>jta</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-jta_1.1_spec</artifactId> <version>1.1</version> </dependency> </dependencies>
当Maven使用一种“最近者胜出”方式解决依赖的时候,它会用到依赖的深度。当使用依赖归类技术(pom类型依赖)的时候,会把依赖推入整个树的更深一层。当在选择用pom归类依赖或者用父POM的dependenctManagement的时候,需要留意这一点。
二 Maven 生命周期
生命周期(lifecyle) | 阶段(phrase) | ||||||||||||||||||||||||||||||||||||||||||
清理(clean) |
pre-clean clean post-clean |
||||||||||||||||||||||||||||||||||||||||||
默认(default)(有时候也称为构建) |
|
||||||||||||||||||||||||||||||||||||||||||
站点(site) |
pre-site site post-site site-deploy 默认绑定到站点生命周期的目标是: 1. site - site:site 2. site-deploy -site:deploy 通过运行如下命令从一个Maven项目生成一个站点: mvn site |
三 Maven 常用命令
maven命令都是由插件来实现的,常用的插件和命令见http://maven.apache.org/plugins/index.html
罗列下常用的命令:
mvn help:system 打印出所有的Java系统属性和环境变量
mvn help:describe -Dplugin=xxxgroupId:xxxartifactId -Dfull
mvn help:describe -Dplugin=exec -Dfull
help:effective-pom 打印项目的有效POM 有效POM是指合并了所有父POM(包括Super POM)后的XML,当你不确定POM的某些信息从何而来时,就可以查看有效POM
help:effective-settings 打印项目的有效settings
mvn help:active-profiles
mvn help:describe -Dcmd=package
mvn help:describe -Dcmd=jar:jar
mvn help:all-profiles 和mvn help:active-profiles 帮助查看项目的Profile
mvn archetype:generate maven3创建maven项目
maven2创建普通java项目,最好用稳定版本
mvn org.apache.maven.plugins:maven-archetype-plugin:2.0-alpha-5:generate
mvn archetype:create -DgroupId=xxx \
-DartifactId=xxx \
-DpackageName=xxx \
-Dversion=1.0
创建Maven的Web项目:
mvn archetype:create -DgroupId=packageName -DartifactId=webappName -DarchetypeArtifactId=maven-archetype-webapp
mvn clean compile 编译 maven3.0之前compile:compile使用javac编译器,从3.0后使用javax.tool.JavaCompiler
mvn test 运行到 test 阶段为止的所有生命周期阶段
mvn test -Dmaven.test.failure.ignore=true 忽略测试失败
mvn install -Dmaven.test.skip=true 跳过单元测试
mvn clean package 打包
mvn clean install 打包并上传到maven本地库
mvn site生成站点信息,在target/site目录下index.html打开可浏览
直接执行main函数命令
mvn install
mvn exec:java -Dexec.mainClass=org.sonatype.mavenbook.weather.Main exec插件不用添加依赖lib包到class路径,它会自动获取依赖包
mvn jetty:run 使用jetty插件启动项目
mvn dependency:resolve 打印出已解决依赖的列表
mvn dependency:tree 项目的整个依赖树
mvn dependency:analyse帮助你发现对于依赖的直接引用想要查看完整的依赖踪迹,包含那些因为冲突或者其它原因而被拒绝引入的构件,如果你有直接使用到的却未声明的依赖,该目标就会发出警告
打开 Maven 的调试标记运行:
mvn install -X
mvn跟开源测试覆盖率统计工具 合成,比如
mvn cobertura:cobertura
之后在target/site/cobertura下看到index.html文件
将依赖的文件安装到本地库
mvn install:install-file
-Dfile=<path-to-file>
-DgroupId=<group-id>
-DartifactId=<artifact-id>
-Dversion=<version>
-Dpackaging=<packaging>
-DgeneratePom=true
四 Maven 插件介绍
一个Maven插件是一个单个或者多个目标的集合。Maven插件的例子有一些简单但核心的插件,像Jar插件,它包含了一组创建JAR文件的目标,Compiler插件,它包含了一组编译源代码和测试代码的目标,或者Surefire插件,它包含一组运行单元测试和生成测试报告的目标。而其它的,更有专门的插件包括:Hibernate3插件,用来集成流行的持久化框架Hibernate,JRuby插件,它让你能够让运行ruby称为Maven构建的一部分或者用
Ruby来编写Maven插件。Maven也提供了自定义插件的能力。一个定制的插件可以用Java编写,或者用一些其它的语言如Ant,Groovy,beanshell和Ruby.
执行命令mvn help:describe -Dplugin=war -Dfull >> a.log
文件a.log中内容如下:
Name: Maven WAR Plugin Description: Builds a Web Application Archive (WAR) file from the project output and its dependencies. Group Id: org.apache.maven.plugins Artifact Id: maven-war-plugin Version: 2.1.1 Goal Prefix: war This plugin has 5 goals: war:exploded Description: Create an exploded webapp in a specified directory. Implementation: org.apache.maven.plugin.war.WarExplodedMojo Language: java Bound to phase: package Available parameters: archive The archive configuration to use. See Maven Archiver Reference. archiveClasses (Default: false) User property: archiveClasses Whether a JAR file will be created for the classes in the webapp. Using this optional configuration parameter will make the compiled classes to be archived into a JAR file and the classes directory will then be excluded from the webapp. cacheFile (Default: ${project.build.directory}/war/work/webapp-cache.xml) Required: true The file containing the webapp structure cache. containerConfigXML User property: maven.war.containerConfigXML The path to a configuration file for the servlet container. Note that the file name may be different for different servlet containers. Apache Tomcat uses a configuration file named context.xml. The file will be copied to the META-INF directory. dependentWarExcludes The comma separated list of tokens to exclude when doing a WAR overlay. Deprecated. Use <overlay>/<excludes> instead dependentWarIncludes The comma separated list of tokens to include when doing a WAR overlay. Default is '**' Deprecated. Use <overlay>/<includes> instead ...... ......
文件中描述了插件的坐标,目标(goals),目标参数,目标执行的mojo类,目标默认绑定阶段
打开其中war目标的mojo类org.apache.maven.plugin.war.WarMojo(在仓库的目录jar中,根据插件的坐标,可以找到jar位置在%本地仓库%/org/apache/maven/plugins/maven-war-plugin)
war:war Description: Build a WAR file. Implementation: org.apache.maven.plugin.war.WarMojo Language: java Bound to phase: package
package org.apache.maven.plugin.war; import java.io.File; import java.io.IOException; import java.util.Arrays; import org.apache.maven.archiver.MavenArchiver; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.DependencyResolutionRequiredException; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.logging.Log; import org.apache.maven.plugin.war.util.ClassesPackager; import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectHelper; import org.codehaus.plexus.archiver.ArchiverException; import org.codehaus.plexus.archiver.jar.ManifestException; import org.codehaus.plexus.archiver.war.WarArchiver; import org.codehaus.plexus.util.StringUtils; public class WarMojo extends AbstractWarMojo { private String outputDirectory; private String warName; private String classifier; private String packagingExcludes; private String packagingIncludes; private WarArchiver warArchiver; private MavenProjectHelper projectHelper; private boolean primaryArtifact; private boolean failOnMissingWebXml; private boolean attachClasses; private String classesClassifier; public WarMojo() { this.primaryArtifact = true; this.failOnMissingWebXml = true; this.attachClasses = false; this.classesClassifier = "classes"; } public void execute() throws MojoExecutionException, MojoFailureException { File warFile = getTargetWarFile(); try { performPackaging(warFile); } catch (DependencyResolutionRequiredException e) { throw new MojoExecutionException("Error assembling WAR: " + e.getMessage(), e); } catch (ManifestException e) { throw new MojoExecutionException("Error assembling WAR", e); } catch (IOException e) { throw new MojoExecutionException("Error assembling WAR", e); } catch (ArchiverException e) { throw new MojoExecutionException("Error assembling WAR: " + e.getMessage(), e); } } private void performPackaging(File warFile) throws IOException, ArchiverException, ManifestException, DependencyResolutionRequiredException, MojoExecutionException, MojoFailureException { getLog().info("Packaging webapp"); buildExplodedWebapp(getWebappDirectory()); MavenArchiver archiver = new MavenArchiver(); archiver.setArchiver(this.warArchiver); archiver.setOutputFile(warFile); getLog().debug("Excluding " + Arrays.asList(getPackagingExcludes()) + " from the generated webapp archive."); getLog().debug("Including " + Arrays.asList(getPackagingIncludes()) + " in the generated webapp archive."); this.warArchiver.addDirectory(getWebappDirectory(), getPackagingIncludes(), getPackagingExcludes()); File webXmlFile = new File(getWebappDirectory(), "WEB-INF/web.xml"); if (webXmlFile.exists()) { this.warArchiver.setWebxml(webXmlFile); } if (!(this.failOnMissingWebXml)) { getLog().debug("Build won't fail if web.xml file is missing."); this.warArchiver.setIgnoreWebxml(false); } archiver.createArchive(getProject(), getArchive()); if (isAttachClasses()) { ClassesPackager packager = new ClassesPackager(); File classesDirectory = packager.getClassesDirectory(getWebappDirectory()); if (classesDirectory.exists()) { getLog().info("Packaging classes"); packager.packageClasses(classesDirectory, getTargetClassesFile(), getJarArchiver(), getProject(), getArchive()); this.projectHelper.attachArtifact(getProject(), "jar", getClassesClassifier(), getTargetClassesFile()); } } String classifier = this.classifier; if (classifier != null) { this.projectHelper.attachArtifact(getProject(), "war", classifier, warFile); } else { Artifact artifact = getProject().getArtifact(); if (this.primaryArtifact) { artifact.setFile(warFile); } else if ((artifact.getFile() == null) || (artifact.getFile().isDirectory())) { artifact.setFile(warFile); } } } protected static File getTargetFile(File basedir, String finalName, String classifier, String type) { if (classifier == null) { classifier = ""; } else if ((classifier.trim().length() > 0) && (!(classifier.startsWith("-")))) { classifier = "-" + classifier; } return new File(basedir, finalName + classifier + "." + type); } protected File getTargetWarFile() { return getTargetFile(new File(getOutputDirectory()), getWarName(), getClassifier(), "war"); } protected File getTargetClassesFile() { return getTargetFile(new File(getOutputDirectory()), getWarName(), getClassesClassifier(), "jar"); } public String getClassifier() { return this.classifier; } public void setClassifier(String classifier) { this.classifier = classifier; } public String[] getPackagingExcludes() { if (StringUtils.isEmpty(this.packagingExcludes)) { return new String[0]; } return StringUtils.split(this.packagingExcludes, ","); } public void setPackagingExcludes(String packagingExcludes) { this.packagingExcludes = packagingExcludes; } public String[] getPackagingIncludes() { if (StringUtils.isEmpty(this.packagingIncludes)) { return { "**" }; } return StringUtils.split(this.packagingIncludes, ","); } public void setPackagingIncludes(String packagingIncludes) { this.packagingIncludes = packagingIncludes; } public String getOutputDirectory() { return this.outputDirectory; } public void setOutputDirectory(String outputDirectory) { this.outputDirectory = outputDirectory; } public String getWarName() { return this.warName; } public void setWarName(String warName) { this.warName = warName; } public WarArchiver getWarArchiver() { return this.warArchiver; } public void setWarArchiver(WarArchiver warArchiver) { this.warArchiver = warArchiver; } public MavenProjectHelper getProjectHelper() { return this.projectHelper; } public void setProjectHelper(MavenProjectHelper projectHelper) { this.projectHelper = projectHelper; } public boolean isPrimaryArtifact() { return this.primaryArtifact; } public void setPrimaryArtifact(boolean primaryArtifact) { this.primaryArtifact = primaryArtifact; } public boolean isAttachClasses() { return this.attachClasses; } public void setAttachClasses(boolean attachClasses) { this.attachClasses = attachClasses; } public String getClassesClassifier() { return this.classesClassifier; } public void setClassesClassifier(String classesClassifier) { this.classesClassifier = classesClassifier; } public boolean isFailOnMissingWebXml() { return this.failOnMissingWebXml; } public void setFailOnMissingWebXml(boolean failOnMissingWebXml) { this.failOnMissingWebXml = failOnMissingWebXml; } }
上面为反编译器显示的jar,注解信息有丢失,war插件的war目标被执行时,WarMojo的execute()方法会被执行,WarMojo类的属性通过注解接收maven传递过来的参数或者默认参数(如果没有传参)。有些Mojo有默认绑定的阶段,当不进行任何设置时,该阶段就会执行这个目标。如compile插件的compile目标默认绑定在default生命周期的compile阶段。
default生命周期jar打包方式绑定的插件:
generate-resources | plugin:descriptor |
process-resources | resources:resources |
compile | compile:compile |
process-test-resources | resources:testResources |
test-compile | compiler:testCompile |
test | surefire:test |
package | jar:jar |
install | install:install |
deploy | deploy:deploy |
default生命周期pom打包方式绑定的插件:
package | site:attach-descriptor |
install | install:install |
deploy | deploy:deploy |
通过编写mojo可以自定义插件,详情见下篇。
相关推荐
apache maven 3.x.x所有Linux, Windows版本下载的百度网盘链接。 apache-maven-3.0.4-bin.tar.gz apache-maven-3.0.4-bin.zip apache-maven-3.0.5-bin.tar.gz apache-maven-3.0.5-bin.zip apache-maven-3.1.0-bin....
apache-maven-3.6.3-bin。apache-maven-3.6.3-bin。apache-maven-3.6.3-bin。apache-maven-3.6.3-bin。apache-maven-3.6.3-bin。apache-maven-3.6.3-bin。apache-maven-3.6.3-bin。apache-maven-3.6.3-bin。apache-...
apache-maven-3.6.1.zip分享给需要的同学 apache-maven-3.6.1.zip分享给需要的同学 apache-maven-3.6.1.zip分享给需要的同学 apache-maven-3.6.1.zip分享给需要的同学 apache-maven-3.6.1.zip分享给需要的同学apache...
apache-maven-3.8.6-bin.zip apache-maven-3.8.6-bin.zip apache-maven-3.8.6-bin.zip apache-maven-3.8.6-bin.zip apache-maven-3.8.6-bin.zip apache-maven-3.8.6-bin.zip apache-maven-3.8.6-bin.zip apache-...
Apache Maven Cookbook is for those who want to learn how Apache Maven can be used for build automation. It is also meant for those familiar with Apache Maven, but want to understand the finer nuances ...
Apache Maven 是一个强大的项目管理和构建工具,主要用于Java项目。它基于项目对象模型(Project Object Model,POM)的概念,能够管理项目的构建、报告和文档。Maven 3.6.0是该工具的一个稳定版本,提供了许多改进...
Apache Maven是一个流行的项目管理工具,主要用于Java项目,帮助开发者自动化构建、文档创建和报告项目信息。 如果你想安装和使用Apache Maven 3.8.3,你需要首先下载这个zip文件,然后解压到适当的目录。一旦解压...
Apache Maven 是一个强大的项目管理和构建工具,主要用于Java应用程序的开发。它基于项目对象模型(Project Object Model,POM)的概念,使得项目的构建、依赖管理、文档生成、代码质量检查等任务变得简单。Apache ...
Apache Maven是Java开发领域广泛应用的一款项目管理工具,它基于项目对象模型(Project Object Model, POM)的概念,能够自动化构建、依赖管理和项目信息管理。在本文中,我们将深入探讨Maven 3.9.6这一版本,以及它...
Apache Maven (apache-maven-3.8.4-bin.zip)是一个软件项目管理和理解工具。基于项目对象模型 (POM) 的概念,Maven 可以从一条中央信息中管理项目的构建、报告和文档。
apache-maven-3.8.8.zip压缩包内容: apache-maven-3.8.8-bin.tar.gz apache-maven-3.8.8-bin.zip apache-maven-3.8.8-src.tar.gz apache-maven-3.8.8-src.zip
Apache Maven 是一个强大的Java项目管理工具,它极大地简化了构建、依赖管理和项目文档的生成过程。Maven 3.6.0是该工具的一个稳定版本,提供了多项改进和新特性,旨在提高开发效率和增强项目的可维护性。 Maven的...
Apache Maven。什么是Maven?简而言之,Maven是我们可以用来构建和管理基于Java的项目的工具。与较旧的构建工具(例如Ant)(同样也是Apache项目)相比,Maven为开发人员提供了一种标准的方法来构建项目,对项目所...
Apache Maven 是一个强大的Java项目管理和综合工具,它简化了构建过程,通过标准化项目结构和自动化构建生命周期。Maven 3.5.0是该工具的一个版本,它包含了多个改进和优化,旨在提升开发效率和用户体验。 在Java...
Apache Maven 是一个强大的项目管理和构建工具,主要用于Java项目。它基于项目对象模型(Project Object Model,POM)的概念,能够管理项目的构建、报告和依赖关系。Maven 的核心理念是通过标准化的构建生命周期和...
Apache Maven 是一个强大的项目管理和构建工具,主要用于Java应用程序的开发。Maven 使用一种标准化的项目对象模型(Project Object Model,POM),使得构建过程、依赖管理、报告生成以及项目的配置变得更加简单。...
Apache Maven 是一个强大的Java项目管理和综合工具,它简化了构建过程,通过标准化项目结构和自动化构建生命周期。在本文中,我们将深入探讨Maven的核心概念、安装步骤以及如何在实际项目中使用它。 **Maven核心...
Apache Maven 是一个强大的项目管理和构建工具,主要用于Java项目。它基于项目对象模型(Project Object Model,POM)的概念,能够管理项目的构建、报告和依赖关系。Maven 的目标是简化项目构建过程,通过标准化构建...
Apache Maven 是一个强大的Java项目管理工具,它简化了构建、依赖管理和项目文档的生成过程。在本文中,我们将深入探讨Apache Maven的安装以及一些实用技巧,帮助开发者更高效地使用这个工具。 首先,我们来讨论...
Apache Maven (apache-maven-3.8.4-src.tar.gz 源代码)是一个软件项目管理和理解工具。基于项目对象模型 (POM) 的概念,Maven 可以从一条中央信息中管理项目的构建、报告和文档。