Basic knowledge
Maven Practice: pom.xml and settings.xml
Pom.xml and settings.xml
Pom.xml and settings.xml are the two most important configuration files in Maven, which determine the core functions of Maven. Although previous articles have mentioned the content in pom.xml and settings.xml in detail, they have both been briefly introduced and the learning and research areas are not detailed. The purpose of this article is to conduct a detailed study of these two important Maven configuration files, which can bring up a lot of Maven topics.
Maven coordinates
First, let's talk about why Maven coordinates are used.
Maven World has a very large number of components, which are commonly used jar, war, and other files. Until Maven introduces the concept of coordinates for these components, we cannot use any one way to uniquely identify all of them. Therefore, if you need to use Spring dependencies, go to the Spring official website to find them; If you need to use the log4j dependency, then look for it on the Apache official website. Due to the diverse styles of various websites, a lot of time is spent searching and browsing the web. Without unified standards and rules, work cannot be automated, and repetitive labor should have been handed over to machines.
Maven has defined a set of rules: any component in the world can be uniquely identified using Maven coordinates. Maven coordinate elements include groupId, artifactId, version, packaging, and classifier. Now, as long as we provide the correct element coordinates, Maven can find the corresponding component. As for where to download, Maven itself has a built-in address for a central warehouse“ http://repo1.maven.org/maven2 This central repository contains the vast majority of popular open source project components in the world, and Mavne will download them there when needed. Of course, you can also configure your own central repository address to download components from your own central repository.
For example, Spring's context:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.6.RELEASE</version>
</dependency>
Take a look at the various elements of subordinates:
GroupId: defines the actual project to which the current Maven project belongs. Due to the fact that Maven projects may not necessarily have a one-on-one relationship with actual projects, such as the SpringFramework, which may correspond to many Maven projects such as core, context, expression, etc., groupId should not correspond to the company or organization that the project belongs to, otherwise artifact will be difficult to define
ArtifactId: Define a Maven module in an actual project. The recommended practice is to use the actual project name as a prefix to the artifactId, which makes it easy to find the actual component
Version: defines the current version of the Maven project, as shown in the spring context in 4.2.6, where RELEASE represents the official release version
Packaging: Define the packaging method for Maven projects. This is not mandatory and is not listed. If not defined, it defaults to the jar packaging method
Classifier: Helps define some auxiliary components for component output, such as xxx javadoc. jar, xxx resources. jar. Auxiliary components correspond to the main component, which cannot be directly defined
The concept of Maven coordinates is roughly like this. Understanding Maven coordinates is an important step in understanding Maven.
Transitive dependency
What is transitive dependency, using Spring as an example. When using Spring, you will rely on other open source class libraries, and there are two ways to do this:
1. Download a large. zip package that contains all Spring's jars, but doing so often introduces many unnecessary dependencies
2. Download only spring related. zip packages and do not include dependencies. In actual use, add other dependencies as needed based on error information
Obviously, both of these approaches are very cumbersome, and Maven's transitive dependency mechanism effectively solves this problem. Open the pom.xml of spring core 4.1.0. RELEASE and I will take a key section:
<dependencies>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.9</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.3</version>
<scope>compile</scope>
</dependency>
...
</dependencies>
For example, if Project A relies on spring core, which in turn relies on commons code and commons logging, then commons code and commons logging are a transitive dependency of Project A. With the transitive dependency mechanism, when using spring core, there is no need to consider what it depends on or worry about introducing extra dependencies. Maven will parse the POMs of each direct dependency and introduce those necessary indirect dependencies into the current project in the form of transitive dependencies.
With the transitive dependency mechanism, on the one hand, it greatly simplifies and facilitates dependency declaration, and on the other hand, in most cases, we only need to care about what the direct dependencies of the project are without considering what transitive dependencies these direct dependencies will introduce. However, sometimes transitive dependencies also have some problems. At this point, we need to clearly know which path the transitive dependency is introduced from, which is called dependency mediation, There are two main principles for relying on mediation:
1. A ->B ->C ->X (1.0), A ->D ->X (2.0). At this point, there are two versions of X on the two dependent paths, and the one that follows the path closest takes precedence. Therefore, X (2.0) will be parsed and used
2. A ->B ->Y (1.0), A ->C ->Y (2.0), Y (1.0), and Y (2.0) have the same dependency length. Starting from Maven 2.0.9, the first declarer priority is followed, that is, the dependency at the top of the order takes precedence
Exclude dependencies
Transitive dependencies can implicitly introduce many dependencies into a project, greatly simplifying the management of project dependencies, but sometimes this feature can also cause problems. For example, there is a situation:
The current project relies on A, which for some reason relies on the SNAPSHOT version of another class library. This SNAPSHOT will become a transitive dependency of the current project, and the instability of the SNAPSHOT will directly affect the current project. In this case, it is necessary to exclude the SNAPSHOT and declare a officially released version of the class library in the current project
Excluding dependencies is simple, let's take a look at the notation:
<dependency>
<groupId>com.alibaba.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>3.2.7</version>
<exclusions>
<exclusion>
<groupId>apache-lang</groupId>
<artifactId>commons-lang</artifactId>
</exclusion>
</exclusions></dependency>
I introduced the dependency of Rocketmq here, but I don't want to rely on Apache lang in Rocketmq, and I want to introduce the dependency myself, so I excluded Apache lang.
It should be noted that when declaring an exception, only the groupId and artifactId are required, without the version element. This is because only the groupId and artifactId are needed to uniquely locate a dependency in the dependency graph. In other words, in the dependencies parsed by Maven, it is impossible to have two dependencies with the same groupId and artifactId but different versions.
settings.xml
The settings. xml contains the basic configuration of Maven, with many elements. Let's take a look at each one
1、proxy
Proxy represents Maven's proxy, let's see how it is written:
<proxies>
<proxy>
<id>optional</id>
<active>true</active>
<protocol>http</protocol>
<username>proxyuser</username>
<password>proxypass</password>
<host>proxy.host.net</host>
<port>80</port>
<nonProxyHosts>local.net|some.host.com</nonProxyHosts>
</proxy>
</proxies>
Proxy is required because often your company requires you to use a security authenticated proxy to access the Internet based on security considerations. In this case, it is necessary to configure an HTTP proxy for Maven in order for it to access the external repository normally and download the required resources. Multiple proxy elements can be configured under proxies. If multiple proxy elements are declared, the first active proxy will take effect by default. If 'active' is true, it indicates the activation of the proxy, while 'protocol' indicates the proxy protocol used. Of course, the most important thing is to specify the correct host name (host) and port (port). If the proxy server requires authentication, configure username and password. The 'non ProxyHost' element indicates which host names do not require a proxy, and multiple host names can be separated by '|'. The wildcard '*' is also supported.
2、repository
The repository represents Maven's central warehouse, as although the components in the default remote warehouse are very large, there will always be times when they do not meet our needs, and other central warehouses will need to be used. Let's take a look at the writing method:
<repository>
<id>public</id>
<name>local private nexus</name>
<url> http://192.168.1.6:8081/nexus/content/groups/public </url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
Multiple repositories can be declared. The ID must be unique, especially note that Maven's built-in central warehouse uses the ID central. If other warehouses declare to also use this ID, it will overwrite the configuration of the central warehouse. Releases and snapshots are more important. The former indicates that the repository is enabled for downloading released versions, while the latter indicates that the repository is disabled for downloading snapshot versions. This way, Maven will go to the repository to download released versions of components instead of downloading snapshot versions.
3、server
Most remote warehouses can be accessed without authentication, but sometimes due to security considerations, authentication information needs to be provided to access some remote warehouses. For security reasons, authentication information is generally only placed in settings. xml, and the server is the authentication element. Take a look at the configuration:
<server>
<id>nexus-releases</id>
<username>deployment</username>
<password>deployment</password>
</server>
The key here is the ID, which must be completely consistent with the ID of the repository element that needs to be authenticated. In other words, the official ID connects the authentication information with the warehouse configuration.
4、mirror
If Warehouse X can provide all the content stored in Warehouse Y, then Warehouse X can be considered as a mirror of Warehouse Y. In other words, any component that can be obtained from Y can be obtained from X. For example“ http://maven.net.cn/content/groups/public/ It's a central warehouse http://repo1.maven.org/maven2/ In China, due to geographical factors, mirrors often provide faster services than central warehouses, which is why mirror is used.
Take a look at the configuration of mirror:
<mirror>
<id>nexus</id>
<name>internal nexus repository</name>