Maven, maven3
There are several people who have just used Maven to say-in a project called "pom. if you declare a dependency in the xml file, you do not need to manually add the jar file. It is not much different from manually managing the dependency.
Of course, this is not the case. Here we record the dependency issues.
Dependency
A dependency can be defined according to the maven coordinate standards.
For example:
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope></dependency>
The above is the most common coordinate attribute, and occasionally you will seeclassifier.
The following is a brief description of the tag:
- GroupId: usually used as a project identifier. For example, the groupId of the SpringFramework project is org. springframework.
It may also be used as the name of the organization to which the project belongs. However, it is difficult to distinguish multiple projects under the organization, and the level should be clear as far as possible.
- ArtifactId: A Project ID with a level lower than the groupId. It is usually used to identify a module, such as spring-aop.
- Classifier: used to identify the attachment of the module.
- Version: the current project version, which should be written in a standard.
- Type: the type of the dependency, which is usually not declared. The default value is jar.
- Scope: The dependency scope. The default value is compile.
- Packaging: package method. The default value is jar.
- Optional: whether the dependency is optional.
- Exclusions: exclude the pass-through dependency.
Scope
When introducing Junit dependencies, you often need to declare test scope:
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope></dependency>
I guess this dependency is used for testing, but it is not completely correct.
You must use classpath to compile the code in Maven, but there are more than one classpath,:
- Compile classpath
- Test classpath
- Run classpath
Maven uses different classpath as needed, and scope can be used to control the relationship between dependencies and the three classpath.
- Compile: This option is used by default and is valid for all three classpath types.
- Test: only valid for the test classpath, as shown in Junit above.
- Provided: It is effective for compiling and testing classpath. For example, the servlet-api dependency posted at the beginning is provided by the app server at runtime, and Maven cannot be repeatedly introduced.
- Runtime: effective for testing and running classpath, and invalid during compilation.
- System: it is valid for compiling and testing classpath, but the specified dependency file location must be displayed through systemPath. You can use system environment variables.
- Import: this parameter is not applicable to any type of classpath. It is used to import dependencyManagement elements from other pom.
The first three methods are usually used.
Scope is used not only to control the relationship between dependencies and classpath, but alsoTransmission.
Transfer dependency? For example, if A depends on B and B on C, A is directly dependent on B, and C is passed dependency.
The scope of A's dependency on B and B on C determines the scope of A's dependency on C.
How to decide? The following is a relational table. Vertical indicates the first dependency, horizontal indicates the second dependency, and cross cells represent the transmission dependency.
| |
Compile |
Test |
Provided |
Runtime |
| Compile |
Compile |
|
|
Runtime |
| Test |
Test |
|
|
Test |
| Provided |
Provided |
|
Provided |
Provided |
| Runtime |
Runtime |
|
|
Runtime |
Consider the dependency, A-> C-> D (1.0) and A-> B-> D (2.0)
What should I do now? It is impossible to introduce two D dependencies.
Maven hasDependency AdjustmentPrinciples:
- The most recent path is preferred.
- When the path length is the same, the Declaration order takes precedence.
In the preceding example, A-> C-> D (1.0) and A-> B-> D (2.0) have the same path length, but the former declares that it is earlier than the latter, therefore, the added passed dependency is D (1.0 ).
In addition, you need to consider such a scenario.
A depends on B, B depends on X and Y, and X and Y are bothOptional dependency, That is<optional>true</optional>And all four are compile.
In this case, X and Y are not passed and are invisible to.
Exclusions
However, dependency adjustment does not solve all the problems. We also need to perform exclusions.Exclude dependency.
For example, A and A are dependent on B in the project, but B is outdated.
In this case, you can use exclusions to exclude the passed dependency and display the declaration of the latest B dependency.
For example:
<dependency> <groupId>com.lowagie</groupId> <artifactId>itext</artifactId> <version>4.2.1</version> <exclusions> <exclusion> <artifactId>bcmail-jdk14</artifactId> <groupId>bouncycastle</groupId> </exclusion> <exclusion> <artifactId>bcprov-jdk14</artifactId> <groupId>bouncycastle</groupId> </exclusion> <exclusion> <artifactId>bctsp-jdk14</artifactId> <groupId>bouncycastle</groupId> </exclusion> </exclusions></dependency>
Properties
It is used to manage attributes in a unified manner. For example, we introduce many spring frameworks:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.0.3 RELEASE</version></dependency><dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.0.3 RELEASE</version></dependency><dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> <version>4.0.3 RELEASE</version></dependency>
It can be seen that the versions are the same. It is too troublesome to modify the versions one by one.
PropertiesThis problem can be solved:
<properties> <spring.version>4.0.3.RELEASE</spring.version></properties>
The introduction of spring can be changed:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version></dependency><dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version></dependency><dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> <version>${spring.version}</version></dependency>
This is indeed a lot of introduction, but you may still hate XML.
Maybe we will not use XML to write the build file in the future.
We may use some plug-ins (such as Polyglot for Maven) or other things (such as Gradle ).
Repository
Maven repositories can be divided into two types:
- Local Repository
- Remote Repository
Maven searches for a dependency from the local repository. If no dependency is found in the remote repository, It is downloaded to the local repository for use.
If all search fails, the system will prompt build failure.
Alternatively, we can put the local jar in the local repository:
Mvn install: install-file-Dfile = jar package path-DgroupId = My groupId-DartifactId = My artifactId-Dversion = My version-Dpackaging = jar
The default path of the local repository is under the user directory..m2/repository/;
This path can be found insettings.xmlFor example:
<localRepository> /usr/local/maven/repository</localRepository>
So where is the remote repository?
Open the org/apache/maven/model/maven-model-builder-3.2.1.jar in $ M2_HOME/lib/pom-4.0.0.xml
The remote repository settings are as follows:
<repositories> <repository> <id>central</id> <name>Central Repository</name> <url>http://repo.maven.apache.org/maven2</url> <layout>default</layout> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories>
Of course, we can also configure other remote repositories, such:
<repositories> <repository> <id>opensesame</id> <name>Alibaba OpenSource Repsoitory</name> <url>http://code.alibabatech.com/mvn/releases/</url> <snapshots> <enabled>false</enabled> </snapshots> </repository></repositories>
Pay attention to some options When configuring remote warehouses.
- Id: the unique identifier of the repository.
- Name: Repository name
- Url: Repository address, usually http
- Layout: default, indicating that the repository layout is maven2 and maven3.
- Release/snapshots
- Enabled: whether the release version or snapshot version is supported
- UpdatePolicy: update policy
- Default Value:
daily
- Always: Check each build
- Never: never check
interval : X: Every X minutes
- ChecksumPolicy: Check policy. The default value is
warnIn additionfailAndignore
Why is release and snapshot different? Cannot be differentiated by version numbers only?
Suppose there are two modules, A depends on B, and B has not been developed yet.
How can developers of Module B obtain this information after each update?
After each update, A developer is prompted to build pull from VCS?
Or constantly change the version number? Indeed, even if B has changed, version is also one of the dependent identifiers.
If the dependency is snapshot, this problem can be solved. A timestamp will be added when snapshot is released. Each time A is built, it will check whether B is up to date. The difference update policy is the aboveupdatePolicy.
You can also executemvn clean install-UForce update.
Remote warehouses are not accessible only when they are accessed. In some warehouses, authentication information is required for security purposes.
Authentication must be performed onsettings.xmlThe following is an example:
<servers> <server> <id>server001</id> <username>my_login</username> <password>my_password</password> <privateKey>${user.home}/.ssh/id_dsa</privateKey> <passphrase>some_passphrase</passphrase> <filePermissions>664</filePermissions> <directoryPermissions>775</directoryPermissions> <configuration></configuration> </server></servers>