Detailed explanation of maven-resources-plugin

This article focuses on these issues:

  • In what scenarios is the maven-resources-plugin used?
  • What is his role?
  • What is the relationship between him and the resources tag configured in pom?
  • Why do some projects use this plugin and others don't?
  • What does the filtering tag in resources do to low?
  • How does maven pack and filter files?

1. What scenarios will be used?

This plug-in will be used as long as we compile the code, even if our project does not declare the plug-in, it will still be used. How to prove it?

We can use mvn clean install in a new maven project without adding any dependencies

By default, Maven binds plug-in goals for some core life cycle phases. When users invoke these phases, the corresponding plug-in goals will automatically perform corresponding tasks. Among them, the two goals of resources and testResources of maven-resources-plugin are bound to the two stages of process-resources and process-test-resources of the default life cycle.

If you don’t understand the life cycle very well, you can read this article. This article will not introduce too much: https://blog.csdn.net/weixin_43888891/article/details/130756192

2. What is his function?

Function: Its function is to copy the files in the resource directory (under the resources directory) of the project to the output directory (target), and the output directory is divided into two, one is the output directory of the test, and the other is the main resource. So it corresponds to the two stages of process-resources and process-test-resources. Of course, the general test directory does not have a resource directory.

What are resource files?

When the .java file is running, it needs to be compiled into a .class file through JRE, and then placed in the target directory, and then when the project is started locally, jvm runs the compiled .class code file in the target directory,

The resource file does not belong to the .java file, which means that it does not need to participate in the compilation work, but it depends on it when running. At this time, you need to put it in the compiled path through the maven-resources-plugin plug-in. In this way, the resource file can be used when our project starts. This is why sometimes our projects often have this file in the code, but the reason why the file cannot be found when running.

If you understand the life cycle, it should be easy to understand the role of the plug-in by looking at the picture below:

Official website introduction: https://maven.apache.org/plugins/maven-resources-plugin/

3. Common configuration of plug-ins

1. Character set encoding

insert image description here

Since the plug-in is a copy resource file, it must involve the encoding of the file. The encodings that can be selected are ASCII, UTF-8 or UTF-16. There are two ways to set the encoding

The first method: use the properties tag to declare project.build.sourceEncoding. After the declaration is completed, the tag in the plug-in <encoding>will take this encoding

<project ...>
 ...
 <properties>
   <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   ...
 </properties>
 ..
</project>

The second is configured through plugins:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-resources-plugin</artifactId>
        <version>3.3.1</version>
        <configuration>
          ...
          <encoding>UTF-8</encoding>
          ...
        </configuration>
      </plugin>
    </plugins>
    ...
  </build>
  ...
</project>

Note: As long as the official website mentions that ${…} can be used to configure, then we can configure it directly in properties without declaring the plug-in.

2. Resources related configuration

2.1, resources configuration structure

The resources tag is actually the configuration of maven-resources-plugin, which is mainly used to configure the resource directory

<build>
	<resources>
	  <resource>
	 		<directory>${project.basedir}/src/main/resources</directory>
	 		<filtering></filtering>
		  <includes>
	  			<include></include>
	 		</includes>
	  	<excludes>
	   			<exclude></exclude>
	  	</excludes>
	 </resource>
	  <!--假如资源目录有多个可以在这里声明-->
	  <resource>
	    ...
	  </resource>
	  
	</resources>
</build>
  • The tag <directory>specifies the resource file directory
  • The tag <includes>specifies only which files are included in the resource file directory to be packaged
  • The tag <excludes>specifies which files are not packaged in the resource file directory
  • label <filtering>is a bool value, the default value is false. Specify whether to perform variable substitution in the configuration file when packaging

2.2, resources default configuration

The so-called default configuration means that the resources tag is not set in the project, and it takes effect by default.

2.2.1, maven super pom default configuration

The maven project inherits a parent pom.xml by default. The configuration mainly includes the following, some of which are the configuration of the maven-resources-plugin plug-in:

For how to view the default inherited pom configuration, you can read this article if you are interested: https://blog.csdn.net/weixin_43888891/article/details/130483451

  <build>
    <directory>${project.basedir}/target</directory>
    <!-- 主资源默认输出的位置 -->
    <outputDirectory>${project.build.directory}/classes</outputDirectory>
    <!--打出来的默认jar、war包名-->
    <finalName>${project.artifactId}-${project.version}</finalName>
    <!-- 测试资源默认输出的位置 -->
    <testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
    <!--默认的主源代码地址-->
    <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
    <scriptSourceDirectory>${project.basedir}/src/main/scripts</scriptSourceDirectory>
    <!--默认的测试源代码地址-->
    <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
    <!--默认的主源代码当中的资源文件地址-->
    <resources>
      <resource>
        <directory>${project.basedir}/src/main/resources</directory>
      </resource>
    </resources>
    <!--默认的测试源代码当中的资源文件地址-->
    <testResources>
      <testResource>
        <directory>${project.basedir}/src/test/resources</directory>
      </testResource>
    </testResources>
  </build>

For example, outputDirectory is the configuration in the maven-resources-plugin plugin as follows:

2.2.2, spring-boot's default configuration for the resources plug-in

Generally, we will inherit a spring-boot-starter-parent for springboot projects, and his pom has made some resources plug-in configurations for us by default:

Like these resources tags are the configuration of the resources plug-in, what role this configuration plays will be discussed later!

In addition, pluginManagement also has the configuration of the resources plugin, as follows:

2.2.3, the final effective configuration of resources

If our project does not inherit spring-boot-starter-parent, then our project inherits a parent pom by default, and the default configuration of resources is as follows:

<resources>
  <resource>
    <directory>${project.basedir}/src/main/resources</directory>
  </resource>
</resources>

If spring-boot-starter-parent is inherited, then the default configuration of our project resources is as follows, and it will replace the default configuration of maven:

<resources>
  <resource>
    <directory>${basedir}/src/main/resources</directory>
    <filtering>true</filtering>
    <includes>
      <include>**/application*.yml</include>
      <include>**/application*.yaml</include>
      <include>**/application*.properties</include>
    </includes>
  </resource>
  <resource>
    <directory>${basedir}/src/main/resources</directory>
    <excludes>
      <exclude>**/application*.yml</exclude>
      <exclude>**/application*.yaml</exclude>
      <exclude>**/application*.properties</exclude>
    </excludes>
  </resource>
</resources>

One thing to note here: If we declare the resources tag in our project, it will replace the resources tag in the inherited parent class. To put it bluntly, the rewritten one will overwrite the inherited one.

2.3. Detailed explanation of tags under resources

2.3.1, the use of filtering

There is also a description on the official website of this tag: https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html

Filtering defaults to false, and its function is to allow any file to be specified to extract the configuration in pom.xml with the syntax of ${...}or .@...@

Usage example:

1. Use the ${keyword} placeholder in the resource file to define variables, such as src/main/resouces/application.properties:

2. At this time, you can define the value of the variable in the pom.xml file

3. If you need to replace the actual value of the variable in the configuration file, you need to enable it <filtering>, and set the value to true. The includes tag is used here to specify the file, that is, the application.properties file is allowed to read the variable value.

<build>
	<resources>
		<resource>
			<directory>src/main/resources</directory>
			<filtering>true</filtering>
               <includes>
                   <include>application.properties</include>
               </includes>
           </resource>
	</resources>
</build>

4. Execute mvn clean package -DskipTestspackaging, and then open the target/classes directory to view the resource files, you will find that the use of @...@the value is successful, but ${...}not successful.

This replacement value is the function of the maven-resources-plugin plug-in. In fact, we can test it without packaging, just change the target of the plug-in by calling:mvn resources:resources

Reason: This is because my project inherits spring-boot-starter-parent, and there is a tag <resource.delimiter> in the springboot xml that changes the value syntax, because spring is afraid of conflicting with other syntax, so @...@use this configuration.

We can also override the configuration of the springboot parent class by manually declaring, so that values ​​can ${...}be obtained through syntax.

<properties>
	<resource.delimiter>${*}</resource.delimiter>
</properties>

5. Specify the value of the variable through the command:mvn clean package -DskipTests -Dusername="lisi"

Note: The priority of the command is higher than the variable value configured in the pom

6. In addition, the definition of variables can not be placed in pom, or other files can be specified, which can be configured through build.filters.filter. Example:

<build>
	<filters>
		<filter>src\main\resources\filters_file.properties</filter>
	</filters>
	<resources>
		<resource>
			<directory>src/main/resources</directory>
			<filtering>true</filtering>
            <includes>
                <include>application.properties</include>
            </includes>
        </resource>
	</resources>
</build>
2.3.2. Why do I have to use includes to specify the file?

There is no need to use variable values. Do not set filtering to true. For this, the official website also clearly states that binary files must not be filtered. I have encountered a bug before that there is an Excel template stored in the resources folder, and the template is exported. Later, it was found to be garbled characters, but it is normal to open Excel through the source code, because the file is filtered. As a result, Excel in the target after compilation is garbled.

insert image description here

2.3.3, the use of include and excludes

There is also a description on the official website of this tag: https://maven.apache.org/plugins/maven-resources-plugin/examples/include-exclude.html

Let's look at the default configuration of springboot. We have already figured out the above link, but the following, why is it allowed, and then it is filtered out using exclude?

In fact, many people in the actual development do not understand this, and the configuration is also a mess. Read the notes written on my pictures twice more, once you understand, you will understand thoroughly!

The include and excludes tags can also appear in a resource at the same time, for example as follows:
to copy a file ending in txt to the target, it is necessary to exclude the file name carrying test.

**/Represents the root directory, both /src/main/resources and /src/main/java belong to the root directory, one *can represent a placeholder, which can be composed of multiple letters

<build>
  ...
  <resources>
    <resource>
      <directory>src/my-resources</directory>
      <includes>
        <include>**/*.txt</include>
      </includes>
      <excludes>
        <exclude>**/*test*.*</exclude>
      </excludes>
    </resource>
    ...
  </resources>
  ...
</build>

2.4. What scenarios need to configure resources?

  1. If there are non-.java files under src/main/java, but they also need to participate in packaging, you need to manually configure resources at this time, because whether it is the parent pom inherited by maven by default or the parent pom of springboot, only the resource files under resources Participate in packing.
  2. If the project inherits spring-boot-starter-parent, then you need to use the application.properties variable value, you can not configure it, because springboot is configured by default, if we still have many configuration files, such as application-dev.properties, application -prod.properties These all need to use variable values. At this time, you need to override the resources configuration of springboot to configure manually.
  3. Some projects will habitually store the upgraded sql of each version in the resources folder. If we do not make any configuration, it will also participate in the packaging. If the sql file is relatively large, the typed jar package must also be large.
  4. The default resource directory is src/main/resources. If the project has files other than the resource directory that need to be packaged, it needs to be manually specified.

I also wrote an article about the resources tag at that time. I didn’t understand it at the time. I can only say that I have drawn some conclusions through personal experiments: https://blog.csdn.net/weixin_43888891/article/ details/122406081

Combining the two articles can basically master it thoroughly!

3. maven-resources-plugin configuration

Detailed configuration on the official website: https://maven.apache.org/plugins/maven-resources-plugin/resources-mojo.html

The maven-resources-plugin plug-in is a built-in plug-in of maven. Even if the project does not declare, it will be accessed when calling. Generally, the project itself does not need to declare, and the resource files are basically controlled through the resources tag.

The default configuration of springboot parent pom is as follows:

  • delimiter: It is to change the form of variable value, as mentioned above.
  • propertiesEncoding: is the character encoding

This is a bug about the plugin that I encountered in the company: https://blog.csdn.net/weixin_43888891/article/details/130089503

After thoroughly mastering resources, I found out that many developments in the company are messy configurations, including me, hahaha

At that time, the filter was used to be true, which caused Excel to fail to open after compression, and then added the following configuration

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-resources-plugin</artifactId>
	<version>3.2.0</version>
	<configuration>
	  <nonFilteredFileExtensions>
		 <!--不应用过滤的其他文件扩展名(已定义的有:jpg, jpeg, gif, bmp, png)-->
		  <nonFilteredFileExtension>xls</nonFilteredFileExtension>
		  <nonFilteredFileExtension>xlsx</nonFilteredFileExtension>
	   </nonFilteredFileExtensions>
	</configuration>
</plugin>

One thing to note here is that springboot sets the maven-resources-plugin in the pluginManagement of the parent pom, and we declare the maven-resources-plugin in the project. In the end, what takes effect is the parent pom+ the configuration we declared:

mvn help:effective-pomYou can view the effective pom through the command

Guess you like

Origin blog.csdn.net/weixin_43888891/article/details/130755755