Maven management module and maven Module
Reposted at: juvenshun.iteye.com/blog/305865
"The city is-gun in the world, and the city is under guard, Lieutenant, and supervisor"-historical records of Qin Shihuang
All real projects managed by Maven should be divided into modules. Each module corresponds to a pom. xml file. They are associated by inheritance and aggregation (also called multi-module. So, why? We are obviously developing a project, dividing modules, and importing Eclipse into N projects, which brings complexity and inconvenience to development.
To explain the cause, suppose there is such a project, a common Java Web application. In this application, we have divided several layers:
- The Dao layer is responsible for database interaction and encapsulates Hibernate interaction classes.
- The Service layer processes the business logic and puts some Service interfaces and implementation-related beans.
- The Web layer is responsible for interacting with the client, mainly including some Structs Action classes.
Corresponding, in a project, we will see some package names:
org.myorg.app.dao org.myorg.app.service org.myorg.app.web org.myorg.app.util
In this way, the entire project framework is clear, but as the project progresses, you may encounter the following problems:
We will find that there is actually no design pattern principle here: "High Cohesion, low coupling ". Although we divide the layers by the package name, you will also say that the dependencies of these packages are unidirectional and there is no package ring dependency. This is good, but not enough, because everything is coupled at the build level. Therefore, we need to use Maven to divide the module.
A simple Maven module structure is as follows:
---- App-parent
| -- Pom. xml (pom)
|
| -- App-util
| -- Pom. xml (jar)
|
| -- App-dao
| -- Pom. xml (jar)
|
| -- App-service
| -- Pom. xml (jar)
|
| -- App-web
| -- Pom. xml (war)
In the preceding example, a parent project (app-parent) aggregates many sub-projects (app-util, app-dao, app-service, and app-web ). Each project, whether parent or child, contains a pom. xml file. Note that the packaging type of each project is marked in parentheses. The parent project can only be pom. Sub-projects include jar or war. Based on the specific content.
The dependencies between these modules are as follows:
App-dao --> app-util
App-service --> app-dao
App-web --> app-service
Pay attention to the dependencies (in most cases, unless you have configured a special dependency scope). app-dao depends on app-util, and app-service depends on app-dao, therefore, app-service also depends on app-util. Similarly, app-web depends on app-dao and app-util.
Replacing package hierarchy with project hierarchy can bring us the following benefits:
Next we will discuss the configuration details of POM, which is actually very simple. Let's first look at the pom. xml of app-parent:
Xml Code
<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>org.myorg.myapp</groupId> <artifactId>app-parent</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>app-util</module> <module>app-dao</module> <module>app-service</module> <module>app-web</module> </modules> </project>
Maven coordinates GAV (groupId, artifactId, version) are configured here. These are all required. In particular, the packaging here is pom. All packages of projects with sub-modules are pom. If packaging is not configured, its default value is jar, which means Maven will compress the project into a jar package.
The important part of this configuration is modules. The sub-modules in this example include app-util, app-dao, app-service, and app-war. In Maven build app-parent, it sorts the build order based on the dependencies between sub-modules, and then builds them in sequence.
This is the configuration required by a parent module. Next we can see that the module complies with the configuration to inherit the parent module. ,
Xml Code
<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"> <parent> <artifactId>app-parent</artifactId> <groupId>org.myorg.myapp</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>app-util</artifactId> <dependencies> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.4</version> </dependency> </dependencies> </project>
The app-util module inherits the app-parent module. Therefore, the POM declares a reference to the app-parent at the beginning, which is implemented through the Maven coordinate GAV. The project app-util itself does not declare the complete GAV. Here we only see artifactId. This POM is correct. The groupId and version are inherited from the parent module by default. In fact, the sub-module inherits everything from the parent module, including dependency and plug-in configuration.
In addition, app-util configures a simple dependency on commons-lang, which is the simplest form of dependency configuration. In most cases, it is also referenced through GAV.
Let's take a look at app-dao, which also inherits from app-parent and relies on app-util:
Xml Code
<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"> <parent> <artifactId>app-parent</artifactId> <groupId>org.myorg.myapp</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>app-dao</artifactId> <dependencies> <dependency> <groupId>org.myorg.myapp</groupId> <artifactId>app-util</artifactId> <version>${project.version}</version> </dependency> </dependencies> </project>
This configuration is almost identical to the app-util configuration. The difference is that the dependency changes, and the app-dao depends on the app-util. Note that the version value is $ {project. version}. This value is an attribute reference pointing to the project/version value of POM, that is, the version corresponding to this POM. Because the version of app-dao inherits from app-parent, the value of app-dao is 1.0-SNAPSHOT. App-util also inherits this value, so we have made consistent versions in all these projects.
Note that app-dao depends on app-util, and app-util depends on commons-lang, app-dao also has dependencies on commons-lang.
The app-service depends on app-dao. Let's take a look at app-web:
Xml Code
<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"> <parent> <artifactId>app-parent</artifactId> <groupId>org.myorg.myapp</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>app-web</artifactId> <packaging>war</packaging> <dependencies> <dependency> <groupId>org.myorg.myapp</groupId> <artifactId>app-service</artifactId> <version>${project.version}</version> </dependency> </dependencies> </project>
App-web depends on app-service, so the dependency on it is configured.
Because app-web is the final application to be deployed, its packaging is war. Therefore, you need a directory src/main/webapp. And in this directory have web application files, such as/WEB-INF/web. xml. Without web. xml, Maven reports build failure. In addition, you may have subdirectories such as/js,/img,/css ....
Let's take a look at how Maven builds the entire project. We run mvn clean install in the app-parent root directory. The output end will be roughly like this:
...
...
[INFO] [war: war]
[INFO] Packaging webapp
[INFO] logging ing webapp [app-web] in [/home/juven/workspaces/ws-others/myapp/app-web/target/app-web-1.0-SNAPSHOT]
[INFO] Processing war project
[INFO] Webapp assembled in [50 msecs]
[INFO] Building war:/home/juven/workspaces/ws-others/myapp/app-web/target/app-web-1.0-SNAPSHOT.war
[INFO] [install: install]
[INFO] Installing/home/juven/workspaces/ws-others/myapp/app-web/target/app-web-1.0-SNAPSHOT.war to/home/juven /. m2/repository/org/myorg/myapp/app-web/1.0-SNAPSHOT/app-web-1.0-SNAPSHOT.war
[INFO]
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] app-parent .................................. .......... SUCCESS [1.191 s]
[INFO] app-util .................................. ............ SUCCESS [1.274 s]
[INFO] app-dao .................................. ............. SUCCESS [0.583 s]
[INFO] app-service .................................. ......... SUCCESS [0.593 s]
[INFO] app-web .................................. ............. SUCCESS [0.976 s]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4 seconds
[INFO] Finished at: Sat Dec 27 08:20:18 PST 2008
[INFO] Final Memory: 3 M/17 M
[INFO] ------------------------------------------------------------------------
Note the Reactor Summary. build the entire project in the desired order. According to our dependency configuration, Maven intelligently arranges the sequence of app-util, app-dao, app-service, and app-web.
Finally, you can find the file app-web-1.0-SNAPSHOT.war in the app-web/target directory, open the war package, and see the WEB-INF in the/commons-lang-2.4.jar/lib directory, and the corresponding app-util, the jar package of app-dao and app-service. Maven automatically handles packaging, and introduces the corresponding jar file according to your dependency configuration.
Using multi-module Maven configuration can help divide projects into modules, encourage reuse, and prevent the POM from becoming too large to facilitate the construction of a module, instead of building the entire project every time, in addition, it makes special control over a module more convenient. This article also provides an actual configuration sample, showing how to use Maven to configure multi-module projects.