Maven配置和使用(三)- 依赖包管理
依赖包管理
对于Maven项目而言,依赖包是它的绝对核心所在,所有的开发项目所需要的*.jar文件都需要通过依赖包的形式来实现相关的配置,但是对于依赖包也需要注意两点问题:包的作用域、包的排除问题1.包的作用域:
在一般进行WEB项目开发的时候,往往都会将所有的开发程序打包为一个*.war文件。那么在这个war文件里面就会存在有lib的目录保存所有的第三方程序开发包文件,于是对于一些重要的开发包,那么就需要将其进行保存,如果不需要的开发包就不希望其输出到lib目录之中。
例如:junit包往往只做测试使用,而实际项目发布的时候这个开发包根本就没有任何用处,所以就不希望其可以自动地输出到war文件之中。
1)为了更好的观察出作用域的问题,首先新建一个web项目
2)编写项目中的pom.xm文件
注意:更换三处jdk版本(编译、项目jdk、FactProjects),引入servelt包,相关插件配置
3)新建一个web.xml文件,注意版本对应 3.1
4)随后来观察两个依赖包的定义情况:
junit和servelt包
作用域的问题:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${srping.version}</version>
</dependency>
junit上scope给的属性是test,而servlet没有给出属性
而scope就属于开发包的作用域,很明显的可以发现当前的junit由于只是一个测试环境下的,所以使用了一个test的作用域,而对于serlvet并没有任何的配置,没有任何的配置指的就是compile作用域
大部分情况下对于依赖包关注最多的就是test和compile
这个时候输出到lib目录下的只有compile范围的开发包,而test范围的开发包并没有输出到lib目录下,因为其设置的范围是test的作用域。
如果将junit的作用域改为compile最打出来的war包lib目录下一共有三个jar包
其中第三个是junit的依赖包。
但是基本上大部分的情况下都会使用test或compile,但是有些开发包,例如:servlet开发包,这个开发包本身都会又Tomcat容器提供,所以这个包只在编译项目的时候有效,那么本质上也没有必要保存到lib目录下,
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${srping.version}</version>
<scope>provided</scope>
</dependency>
表示该程序包的实现将依赖于容器机制负责完成。
这个时候如果在进行打包的时候,servelt开发包也不会自动地进行编译(打包处理)
此时添加spring包:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${srping.version}</version>
</dependency>
编译打包后效果如图:
- 2.依赖包的排除问题:
发现在进行包的依赖控制的时候,这个时候往往会发现存在有其他依赖关系,例如:我们的A项目去依赖B包的时候,发现B包又依赖于C包,但是我们的配置之中发现项目A也要去引用C包,这样一来就有可能造成jar包的冲突,所以就不希望B自动依赖的C包加入到项目的编译里面,这样就需要进行一个包的排除处理。
比如:spring依赖了commons-logging包,会自动生成并导入
项目添加依赖包commons-logging
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
1.原始的配置,里面存在有重复的依赖关系。
2.可以借助于eclipse中的工具查看依赖关系。
可以清晰的看到包的层次关系和依赖关系
3.实现包的排除处理:
手松处理,观察pom.xml文件对应的配置变化:
所以此时整个项目之中只会存在有一个公共的commons-logging的开发包存在,这样的时候就可以避免重复包冲突:
实际之中,这个重复的排查是一个非常麻烦的事情,一定要耐心排除
一个项目可以导入另外一个项目打成的jar包
我们自己在项目之中所建立的maven项目之间也是可以互相导入处理的,只需要咱找pom.xml文件的要求编写相关的引用即可
- *继承关系
通过之前的演示现在可以发现一个问题,几乎每一个pom.xml文件都需要进行如下的几项基本配置:属性、相关插件
于是这个时候就可能产生这样的一些问题:假设说你现在要开发的是一个公司很庞大的项目,那么这个很庞大的项目里边会存在很多子项目。
继承处理:
父类中定义公共配置:
如何在项目中实现继承关系。
1.假设现在最大的父项目为:cn.mldn.base,这个项目将需要提供一个公共的pom.xml文件,所以这个项目在搭建的时候应该只搭建最基础的Maven项目环境,而重点就应该放在pom.xml文件的编写上,由于该项目只是具备有一个pom的功能,所以这个项目的类型就应该设置为pom
范例:建立一个新的base/pom.xml文件。
关键编写pom.xml文件
注意:packaging 为pom
相关插件导入base的pom.xml中
定义所有要使用的相关处理插件:
完成了父的项目的基础搭建
以后所有的子项目中使用的pom文件中的内容需要继承base父类
此时所有核心的配置选项都定义在父项目之中,而后每一个子项目都需要引用这个父项目中的相关定义:
2.假设现在的公司里面需要创建一个OA的子项目,于是这个时候依然创建一个普通的maven项目,为了演示方便直接建立一个maven的web项目(web-app),这个项目的版本一定要由父项目来决定。(全局属性和插件信息)
范例:修改OA中的pom.xml文件,实现继承关系。
继承之后的pom不在需要groupId和version信息。因为从父项目已继承过来。
可以直接使用全局属性:
相关的属性以及配置的插件都会自动的通过父项目继承而来。
此时项目之中需要的版本都在父类之中做了定义:
所有子类同一管理,更换版本直接修改父类即可
实际上在整个父类的开发里面也提供有一些依赖包的管理问题,也就是说在父类里边直接导入好所需要的开发包。
父项目中base/pom.xml中定义要使用的开发包:
子类里边删除,报错了,这个时候对于子项目而言,实际上也需要继续导入开发包,与之前最大的区别是不需要管理版本编号问题了。
发现现在在子项目里边依然需要导入开发包,唯一的区别是不需要导入版本号了,但是好像这个功能有点然并卵!
建议只在父项目设置插件和全局属性,不建议在父类中导入需要的依赖包,全部在子项目中配置依赖包
- 构建设置
在实际的项目开发过程之中肯定你自己一定会有一个你自己的开发环境,那么当整个组的项目编写完成之后,一定会有一个内部的测试环境,等真正项目上线之后那么也一定会有一套线上的相关配置环境。
从实际的开发来说,项目的开发的基本环境的配置一般都会有三类。
例如:以数据库的连接为例,一般进行框架开发的时候(SSM、Spring、Shiro、MyBatis),那么一般都需要建立一系列的*.properties文件以保存相关的环境属性,于是现在针对于这样的配置文件,那么就有可能会分为三种类型:
1)dev(开发者):数据库的连接地址为192.168.1.101:3306/dev
2)beta(综合测试环境):数据库的连接地址为192.168.1.250:3308/beta
3)product(综合测试环境):数据库的连接地址为10.5.6.78:3308/product
那么一般情况下都会准备出三套配置文件,而后在将项目打包为.war文件之后希望可以根据不同的环境选择不同的配置属性(.properties)文件。所以这样的配置就成为构建配置,而幸运的是,Maven支持这样的动态选择的打包操作。
1.建立一个保存所有配置文件的源目录:src/main/profiles;
在此目录之中分别创建三个子目录:
dev:保存所有开发的相关环境资源配置;
beta:保存所有测试的相关环境资源配置;
product:保存所有的线上环境的资源配置
为了咱们方便观察,在每一个文件夹下都需要有一个conf子文件夹,保存有相应的资源文件项:
建立的目的:在整体的设计过程中提供有三组不同的运行的环境配置
此时已经提供有三组不同的开发环境的配置项,当然整体的配置项要想生效,一定是需要在pom.xml文件中进行相关定义的。
2.遗憾的是,这个时候并不能够进行打包的控制,还需要将profiles中的其中一个子目录设置为源代码目录,否则内容将无法输出。
比如:本次将dev的目录设置为源代码目录。
右击项目 –属性
3.一旦要接触到框架开发,那么会面临一个新的问题,就是开发框架之中需要编写大量的*.xml配置文件,例如现在流行的SSM开发框架,那么就需要编写有spring、mabatis、shiro的相关配置文件项。
—-在src/main/resources目录下建立一个conf的子目录,而后在这个子目录下面分别建立三个子目录:spring、shiro、mybatis,分别保存不同框架的配置文件。
这些配置文件项都要输出到web项目中的WEB-INF的class目录下
4.如果需要这些配置文件起作用,那么就需要修改pom.xml配置文件,需要配置profile和build
重点配置:
<profiles> <!-- 明确的描述出要使用的不同环境的配置文件 -->
<profile>
<id>dev</id> <!-- 明确的描述出本配置文件的编号,一般会与文件目录重名 -->
<properties> <!-- 明确的描述出此配置项对应的路径 -->
<profile.dir>${profiles.dir}/dev</profile.dir>
</properties>
<activation> <!-- 默认如果没有指派profile的编号,默认使用此配置 -->
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>beta</id> <!-- 明确的描述出本配置文件的编号,一般会与文件目录重名 -->
<properties> <!-- 明确的描述出此配置项对应的路径 -->
<profile.dir>${profiles.dir}/beta</profile.dir>
</properties>
<activation> <!-- 默认如果没有指派profile的编号,默认不使用此配置 -->
<activeByDefault>false</activeByDefault>
</activation>
</profile>
<profile>
<id>product</id> <!-- 明确的描述出本配置文件的编号,一般会与文件目录重名 -->
<properties> <!-- 明确的描述出此配置项对应的路径 -->
<profile.dir>${profiles.dir}/product</profile.dir>
</properties>
<activation> <!-- 默认如果没有指派profile的编号,默认不使用此配置 -->
<activeByDefault>false</activeByDefault>
</activation>
</profile>
</profiles>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jdk.version>1.7</jdk.version><!-- 定义一个描述jdk版本的公共属性 -->
<junit.version>4.12</junit.version>
<srping.version>5.0.7.RELEASE</srping.version>
<!-- 将所有资源文件的配置路径作为属性出现 -->
<profiles.dir>src/main/profiles</profiles.dir>
<resources.dir>src/main/resources</resources.dir>
</properties>
<build>
<finalName>em</finalName>
<defaultGoal>package</defaultGoal> <!-- 在打包的时候进行使用 -->
<resources> <!-- 可以理解为控制资源文件是否使出的配置 -->
<resource>
<directory>${profile.dir}</directory> <!-- 注意 此处要定义profile的输出路径 -->
<filtering>false</filtering> <!-- 替换作用 -->
</resource>
<resource>
<directory>${resources.dir}</directory>
<filtering>false</filtering> <!-- 替换作用 -->
</resource>
</resources>
</build>
filtering会做替换:
5.配置完成之后对项目进行更新,随后为其进行打包的操作处理。
由于本次设置了默认打包的profile的id名称为dev;所以此处不需要写profiles
打出来的包自动加载了dev环境下的配置信息
如果以后要更换其他的配置项,那么最简单的做法就是直接使用profile的名字。例如:
变换到线上环境:
可以通过不同的profile来实现不同环境的开发包的打包处理操作,这一点在很多情况下非常好用。
6.在进行资源配置的时候还可以设置必须包含的内容,以及排除的内容,
比如:新建hello.properties,此文件打包的时候不需要输出
<build>
<finalName>em</finalName>
<defaultGoal>package</defaultGoal> <!-- 在打包的时候进行使用 -->
<resources> <!-- 可以理解为控制资源文件是否使出的配置 -->
<resource>
<directory>${profile.dir}</directory> <!-- 注意 此处要定义profile的输出路径 -->
<filtering>false</filtering> <!-- 替换作用 -->
</resource>
<resource>
<directory>${resources.dir}</directory>
<filtering>false</filtering> <!-- 替换作用 -->
<includes> <!-- 明确表示 在进行资源选择的时候必须包含目录下的文件 -->
<include>**/spring.common.xml</include>
</includes>
<excludes> <!-- 明确表示 在进行资源选择的时候不包含任何目录下的*.properties文件 -->
<exclude>**/*.properties</exclude>
</excludes>
</resource>
</resources>
执行结果:
这两个配置并不是很建议大家去使用,在实际开发之中,这样的包含处理和不包含处理意义并不是很大,在你文件目录里面最好保存你所需要的内容,如果不需要,不建议保存。
- Maven生命周期
在整个Maven里面,可以发现所有的功能都是围绕着项目的包的依赖管理、程序的编译打包的处理。而对于Maven本身也有一套自己的生命周期(意义不大)
在进行项目的发布的时候会发现,所有的*.java文件程序会自动进行编译处理。所以这个编译的过程是由Maven自己来完成的,而在编译完成之后会自动使用cn/main/test下的测试程序对程序进行测试(自动做的)。
而且,详细生命周期解释:
针对于Maven生命周期的控制操作,都会在自动地Eclipse中有所体现,帮助用户使用。
我们大部分情况下处理的时候都会采用简单的模式来完成,例如:可以设置一些命令:clean compile test package
如果不在eclipse中执行,也可以在cmd下使用Maven常用命令来执行:
现在一般进行Maven项目开发的时候往往都会借助于Eclipse、Idea等工具进行开发,这样的确是很方便,毕竟在项目里面除了Maven这种项目管理工具之外,可能还要集成其它项目管理工具,例如:SVN、GIT等。
生命周期中最重要的就是Maven常见的操作命令。