Maven创建Java项目
mvn archetype:generate "-DgroupId=<包名>" "-DartifactId=<项目名>" "-DarchetypeArtifactId=maven-archetype-quickstart" "-DinteractiveMode=false"
两种设置java版本的方法,修改pom.xml
- 配置properties节点下的maven编译器信息
<properties>
<maven.compiler.target>15</maven.compiler.target>
<maven.compiler.source>15</maven.compiler.source>
</properties>
- 配置build > plugins > plugins > configuration 节点下的source和target节点值
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>15</source>
<target>15</target>
</configuration>
</plugin>
</plugins>
运行结果如下
Maven 常用的打包方式
插件 | 功能 |
---|---|
maven-jar-plugin | maven 默认打包插件,用来创建 project jar |
maven-shade-plugin | 打可执行包,executable(fat) jar |
maven-assembly-plugin | 支持自定义打包方式 |
spring-boot-maven-plugin | spring boot 定制的打包方式 |
java 项目打包
maven-jar-plugin(默认打包工具)
该组件虽然是默认添加的,但没有显示指定 MainClass 打包出来的 jar 包依旧无法运行,会提示没有主清单属性。
修改 pom.xml,添加如下配置
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass> ${包名.MainClass类名} </mainClass>
</manifest>
</archive>
</configuration>
</plugin>
在没有引用任何依赖的情况下,上面的打包方式是可以的(即使不做任何配置,也可以正常运行)。但如果你的项目有引用第三方lib,则需要额外添加插件maven-dependency-plugin。它的 addClasspath 和 classpathPrefix 表明,会把 lib 下的jar作为第三方依赖加入 package 里,去target目录下也可以发现多了个lib目录。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy</id>
<phase>compile</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/lib
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
maven-shade-plugin
<project>
<build>
<plugins>
<!-- maven-shade-plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass> ${包名.MainClass类名} </mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
maven-assembly-plugin
<!-- Maven Assembly Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<!-- get all project dependencies -->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<!-- MainClass in mainfest make a executable jar -->
<archive>
<manifest>
<mainClass> ${包名.MainClass类名} </mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<!-- bind to the packaging phase -->
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
spring boot 项目打包
spring-boot-maven-plugin
设置打包类型
spring 之前基本都是打成 war 类型,现在以 jar 类型为主(若未配置,默认在 target 目录下生成 jar 包),查看 pom.xml
<?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">
<!-- ... -->
<packaging>jar</packaging>
<!-- ... -->
</project>
配置插件
创建 spring boot 的时候,自动帮你添加了 spring-boot-maven-plugin,即使不对其进行任何配置操作,也可以直接使用 mvn package
命令将其打包!
对于 spring-boot-starter-parent 的项目, 需要在properties中指定start-class启动类。
- layout 属性用来指定打成什么类型
类型 | Main-Class | 含义 |
---|---|---|
jar | org.springframework.boot.loader.JarLauncher | 可执行的 jar |
war | org.springframework.boot.loader.warLauncher | 可执行war,需要的servlet容器依赖位于WEB-INF/lib-provided |
zip | org.springframework.boot.loader.PropertiesLauncher | DIR,类似于JAR |
module | 将所有的依赖库打包(scope为provided的除外),但是不打包Spring Boot的任何Launcher | |
none | 将所有的依赖库打包,但是不打包Spring Boot的任何Launcher |
- 构建目标
目标 | 含义 |
---|---|
run | 运行 spring boot 项目 |
repackage | 默认goal。在mvn package之后,再次打包可执行的jar/war,同时保留mvn package生成的jar/war为.origin |
start / stop | 在mvn integration-test阶段,进行Spring Boot应用生命周期的管理 |
build-info | 生成Actuator使用的构建信息文件build-info.properties |
<?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.3.2.RELEASE</version>
<relativePath />
</parent>
<properties>
<start-class> ${包名.MainClass类名} </start-class>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>14</java.version>
</properties>
<build>
<plugins>
<!-- ... -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>${start-class}</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- ... -->
</plugins>
</build>
</project>
打包
执行 mvn package spring-boot:repackage
进行打包,在 target 目录下就会生成打包好的 jar 文件了。使用 nautilus target/
可以直接打开 target 所在的文件管理器进行操作
打开 jar 中的 /META-INF/MANIFEST.MF 文件,可以看到之前配置的 Main-Class 和 layout 类型对应的 Start-Class
Manifest-Version: 1.0
Created-By: Maven Jar Plugin 3.2.0
Build-Jdk-Spec: 14
Implementation-Title: demo
Implementation-Version: 0.0.1-SNAPSHOT
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.example.demo.DemoApplication
Spring-Boot-Version: 2.3.2.RELEASE
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
画蛇添足
spring 默认自带了 spring-boot-maven-plugin 来打包程序,如果又引入 maven-shade-plugin 打包时会报如下错误
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-shade-plugin:3.2.4:shade (default) on project demo: Unable to parse configuration of mojo org.apache.maven.plugins:maven-shade-plugin:3.2.4:shade for parameter resource: Cannot find ‘resource’ in class org.apache.maven.plugins.shade.resource.ManifestResourceTransformer -> [Help 1]
打包失败
执行 mvn package
报如下错误,提示 ApplicationTests
头部没找到 @SpringBootConfiguration
注解。
无稽之谈是不是,spring-boot-starter-test
模块的注解通常都是 @SpringBootTest
解决办法是:删除pom.xml里的这段话
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>