SpringBoot & Maven dependency, configuration separation and packaging

Posted by seavers on Wed, 23 Feb 2022 05:41:27 +0100

introduce

With the iteration of technology, SpringBoot is widely used in our daily development. When using maven to build traditional web applications, we package the projects into war packages and deploy them in tomcat. All directory resources are separated, which is very convenient for the modification of configuration files. However, if you use the packaging tool of SpringBoot, it is packaged into a jar file by default and can be run directly through java commands. The project will run in the web server embedded in SpringBoot. We can make a horizontal comparison between the two packaging methods:

war packagejar package
Deployment modeIt needs to be placed in an external web container to runYou can run it directly with java commands, and the program will run in the embedded web container
Document compositionEach resource file is separated, such as lib, classes, configuration files, etc. it is convenient to modify and replace filesAll resource files are packaged together, and it is troublesome to modify and replace files

It is precisely because the packaging method of jar package packages all resources together, so the volume of jar package will be relatively large. It is very troublesome to deploy hundreds of megabytes of jar packages on the server. Maybe the code accounts for only 20% of the size and the dependent jar packages account for 70% of the size. However, for only small changes in the code, the whole project also needs to be repackaged and deployed. At the same time, it is not very convenient to modify some configuration files.

Before modification

There is only one jar package with a size of 53.5MB

After modification


It can be seen that after separating dependencies, the volume of jar package is significantly reduced, and we can separate the configuration file separately to facilitate our future modification.

to configure

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.5.0</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.yousan</groupId>
	<artifactId>springboot-maven-package</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>springboot-maven-package</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>1.8</java.version>
        <!-- Path exported after packaging -->
		<package.path>${project.build.directory}/app</package.path>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
        ......
	</dependencies>

	<build>
		<plugins>
			<!-- Online deployment JAR Start detach dependency lib And configuration -->
			<!-- pack jar -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
				<configuration>
					<!-- Do not package resource files -->
					<excludes>
						<exclude>*.**</exclude>
					</excludes>
					<archive>
						<manifest>
							<addClasspath>true</addClasspath>
							<!-- MANIFEST.MF in Class-Path Add prefix -->
							<classpathPrefix>lib/</classpathPrefix>
							<!-- jar The package does not contain a unique version ID -->
							<useUniqueVersions>false</useUniqueVersions>
							<!-- Specify entry class -->
							<mainClass>com.yousan.SpringbootMavenPackageApplication</mainClass>
						</manifest>
						<!--  Specify the configuration file directory so that jar The runtime will find the files in the same directory config Find under folder  -->
						<manifestEntries>
							<Class-Path>config/</Class-Path>
						</manifestEntries>
					</archive>
					<outputDirectory>${package.path}</outputDirectory>
				</configuration>
			</plugin>
			<!-- Copy dependency copy-dependencies -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-dependency-plugin</artifactId>
				<executions>
					<execution>
						<id>copy-dependencies</id>
						<phase>package</phase>
						<goals>
							<goal>copy-dependencies</goal>
						</goals>
						<configuration>
							<outputDirectory> ${package.path}/lib/ </outputDirectory>
						</configuration>
					</execution>
				</executions>
			</plugin>
			<!-- Copy resource files copy-resources -->
			<plugin>
				<artifactId>maven-resources-plugin</artifactId>
				<executions>
					<execution>
						<id>copy-resources</id>
						<phase>package</phase>
						<goals>
							<goal>copy-resources</goal>
						</goals>
						<configuration>
							<resources>
								<resource>
									<directory>src/main/resources</directory>
									<!--  Specify who will participate in the build resource -->
									<includes>
										<include>*.**</include>
									</includes>
								</resource>
							</resources>
							<outputDirectory>${package.path}/config</outputDirectory>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

Topics: Java Maven Spring Boot