我们使用Maven应用到实际项目的时候,需要将项目分成不同的模块。这个时候,Maven的聚合特性能够把项目的各个模块聚合在一起构件,而Maven的继承特性则能帮助抽取各模块相同的依赖和插件等配置。在简化POM的同时,还能促进各个模块配置的一致性。下面以具体项目来讲解:
1. 项目结构
以上有五个项目分别为user-parent, user-core, user-log, user-dao, user-service. 其中user-parent项目为其他项目的父项目,只是帮助其他模块构建的工具,它本身并无实质的内容,只有一个pom.xml文件。
2. user-parent的pom.xml详情如下(下文简称为父POM)
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
|
<
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
>com.liangbo.user</
groupId
>
<
artifactId
>user-parent</
artifactId
>
<
version
>0.0.1-SNAPSHOT</
version
>
<
packaging
>pom</
packaging
>
<
modules
>
<
module
>../user-core</
module
>
<
module
>../user-dao</
module
>
<
module
>../user-log</
module
>
<
module
>../user-service</
module
>
</
modules
>
<
properties
>
<
project.build.sourceEncoding
>UTF-8</
project.build.sourceEncoding
>
<
junit.version
>4.10</
junit.version
>
<
mysql.driver
>com.mysql.jdbc.Driver</
mysql.driver
>
<
mysql.url
>jdbc:mysql://localhost:3306/mysql</
mysql.url
>
<
mysql.username
>root</
mysql.username
>
<
mysql.password
>password</
mysql.password
>
</
properties
>
<
dependencyManagement
>
<
dependencies
>
<
dependency
>
<
groupId
>junit</
groupId
>
<
artifactId
>junit</
artifactId
>
<
version
>${junit.version}</
version
>
<
scope
>test</
scope
>
</
dependency
>
<
dependency
>
<
groupId
>com.liangbo.user</
groupId
>
<
artifactId
>user-core</
artifactId
>
<
version
>0.0.1-SNAPSHOT</
version
>
</
dependency
>
<
dependency
>
<
groupId
>com.liangbo.user</
groupId
>
<
artifactId
>user-log</
artifactId
>
<
version
>0.0.1-SNAPSHOT</
version
>
</
dependency
>
<
dependency
>
<
groupId
>com.liangbo.user</
groupId
>
<
artifactId
>user-dao</
artifactId
>
<
version
>0.0.1-SNAPSHOT</
version
>
</
dependency
>
<
dependency
>
<
groupId
>com.liangbo.user</
groupId
>
<
artifactId
>user-log</
artifactId
>
<
version
>0.0.1-SNAPSHOT</
version
>
<
exclusions
>
<
exclusion
>
<
groupId
>log4j</
groupId
>
<
artifactId
>log4j</
artifactId
>
</
exclusion
>
</
exclusions
>
</
dependency
>
<
dependency
>
<
groupId
>log4j</
groupId
>
<
artifactId
>log4j</
artifactId
>
<
version
>1.2.9</
version
>
</
dependency
>
<
dependency
>
<
groupId
>commons-logging</
groupId
>
<
artifactId
>commons-logging</
artifactId
>
<
version
>1.1.1</
version
>
</
dependency
>
<
dependency
>
<
groupId
>org.hibernate</
groupId
>
<
artifactId
>hibernate-core</
artifactId
>
<
version
>3.6.10.Final</
version
>
</
dependency
>
<
dependency
>
<
groupId
>log4j</
groupId
>
<
artifactId
>log4j</
artifactId
>
<
version
>1.2.16</
version
>
</
dependency
>
<
dependency
>
<
groupId
>mysql</
groupId
>
<
artifactId
>mysql-connector-java</
artifactId
>
<
version
>5.1.26</
version
>
</
dependency
>
<
dependency
>
<
groupId
>org.slf4j</
groupId
>
<
artifactId
>slf4j-log4j12</
artifactId
>
<
version
>1.7.5</
version
>
</
dependency
>
<
dependency
>
<
groupId
>javassist</
groupId
>
<
artifactId
>javassist</
artifactId
>
<
version
>3.12.1.GA</
version
>
</
dependency
>
</
dependencies
>
</
dependencyManagement
>
<
build
>
<
pluginManagement
>
<
plugins
>
<
plugin
>
<
groupId
>org.apache.maven.plugins</
groupId
>
<
artifactId
>maven-source-plugin</
artifactId
>
<
version
>2.2.1</
version
>
<
executions
>
<
execution
>
<
phase
>package</
phase
>
<
goals
><
goal
>jar-no-fork</
goal
></
goals
>
</
execution
>
</
executions
>
</
plugin
>
<
plugin
>
<
groupId
>org.codehaus.mojo</
groupId
>
<
artifactId
>sql-maven-plugin</
artifactId
>
<
version
>1.5</
version
>
<
dependencies
>
<
dependency
>
<
groupId
>mysql</
groupId
>
<
artifactId
>mysql-connector-java</
artifactId
>
<
version
>5.1.26</
version
>
</
dependency
>
</
dependencies
>
<
configuration
>
<
driver
>${mysql.driver}</
driver
>
<
url
>${mysql.url}</
url
>
<
username
>${mysql.username}</
username
>
<
password
>${mysql.password}</
password
>
<
sqlCommand
>
create database IF NOT EXISTS maven_test
</
sqlCommand
>
</
configuration
>
<
executions
>
<
execution
>
<
phase
>package</
phase
>
<
goals
>
<
goal
>execute</
goal
>
</
goals
>
</
execution
>
</
executions
>
</
plugin
>
<
plugin
>
<
groupId
>org.apache.maven.plugins</
groupId
>
<
artifactId
>maven-rar-plugin</
artifactId
>
<
version
>2.3</
version
>
<
executions
>
<
execution
>
<
phase
>package</
phase
>
<
goals
><
goal
>rar</
goal
></
goals
>
</
execution
>
</
executions
>
</
plugin
>
</
plugins
>
</
pluginManagement
>
</
build
>
</
project
>
|
上面的pom.xml文件既有Maven的聚合特性又有继承特性。这样做是为了更加方便管理其他模块。其中元素modules,是实现聚合的最核心配置。多个子模块之间的pom有很多的相同的配置,这时候可以全部提取出来放到父项目中。重复往往就意味着更多的劳动和更多的潜在的问题。那么子模块如何来继承他的父项目呢?
3. 下面来看下user-core项目pom.xml的配置
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
56
57
58
59
60
61
62
63
64
65
66
67
68
|
<
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
>
<
parent
>
<
groupId
>com.liangbo.user</
groupId
>
<
artifactId
>user-parent</
artifactId
>
<
version
>0.0.1-SNAPSHOT</
version
>
<
relativePath
>../user-parent/pom.xml</
relativePath
>
</
parent
>
<
artifactId
>user-core</
artifactId
>
<
packaging
>jar</
packaging
>
<
name
>user-core</
name
>
<
url
>http://maven.apache.org</
url
>
<
dependencies
>
<
dependency
>
<
groupId
>junit</
groupId
>
<
artifactId
>junit</
artifactId
>
</
dependency
>
<
dependency
>
<
groupId
>org.hibernate</
groupId
>
<
artifactId
>hibernate-core</
artifactId
>
</
dependency
>
<
dependency
>
<
groupId
>log4j</
groupId
>
<
artifactId
>log4j</
artifactId
>
</
dependency
>
<
dependency
>
<
groupId
>mysql</
groupId
>
<
artifactId
>mysql-connector-java</
artifactId
>
</
dependency
>
<
dependency
>
<
groupId
>org.slf4j</
groupId
>
<
artifactId
>slf4j-log4j12</
artifactId
>
</
dependency
>
<
dependency
>
<
groupId
>javassist</
groupId
>
<
artifactId
>javassist</
artifactId
>
</
dependency
>
</
dependencies
>
<
build
>
<
plugins
>
<
plugin
>
<
groupId
>org.apache.maven.plugins</
groupId
>
<
artifactId
>maven-source-plugin</
artifactId
>
</
plugin
>
<
plugin
>
<
groupId
>org.codehaus.mojo</
groupId
>
<
artifactId
>sql-maven-plugin</
artifactId
>
</
plugin
>
<
plugin
>
<
groupId
>org.apache.maven.plugins</
groupId
>
<
artifactId
>maven-rar-plugin</
artifactId
>
</
plugin
>
</
plugins
>
</
build
>
</
project
>
|
其中设置好relativePath非常重要,不然无法找到父POM。这时候子POM中只需要配置groupId和artifactId就可以了。
4. 依赖管理和插件管理
上述子POM配置简单了很多,是因为父POM引用了依赖管理和插件管理的概念。如果父POM没有配置依赖管理和插件管理的话,继承它的子模块会将父所有的依赖和插件都继承下来,显然这是不可行的。接下来讲下如何配置的:
Maven提供的dependencyManagement元素既能让子模块继承到父模块的依赖配置,又能保证子模块依赖使用的灵活性。在dependencyManagement元素下的依赖声明不会引入实际的依赖,不过它可以约束dependencies下的依赖使用。插件管理同上,需要在父POM中加入pluginManagement元素。
最后,说下聚合与继承的关系,多模块Maven中的聚合与继承其实是两个不同的概念,其目的是不同的。前者主要是为了方便快速构建项目,后者主要是为了消除重复配置。