在使用maven构建springboot项目时,springboot相关jar包可以使用parent方式引入(即在pom.xml的parent节点引入springboot的GAV:org.springframework.boot:spring-boot-starter-parent:2.1.1.RELEASE),也可以使用非parent方式引入(即在pom的dependencyManagement节点引入springboot的GAV:org.springframework.boot:spring-boot-dependencies:2.1.1.RELEASE)。同时,在打包时,我们可以打成jar包,也可以打成war包,本文旨在梳理各引入、打包方式的异同。
1. parent方式引入,打成jar包
parent方式,即在pom文件中,将springboot的依赖当成项目的parent引入,pom文件示例如下:
<?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
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 引入springboot的parent -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
</parent>
<groupId>com.gitee.funcy</groupId>
<artifactId>springboot-parent-jar</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>springboot parent jar打包方式</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
</properties>
<dependencies>
<!-- springboot 的基础依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- springboot 的web 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- maven编译插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<!-- springboot编译插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!-- 其他内容不用指定,因为 spring-boot-starter-parent 已经指定了-->
</plugin>
</plugins>
</build>
</project>
添加一个controller:
package com.gitee.funcy.mavenparent.jar.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* {这里添加描述}
*
* @author funcy
* @date 2019-12-13 10:43 下午
*/
@RestController
public class IndexController {
@RequestMapping("/")
public String helloWorld() {
return "hello world";
}
}
再引入启动类:
package com.gitee.funcy.mavenparent.jar;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* {这里添加描述}
*
* @author funcy
* @date 2019-12-13 10:36 下午
*/
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
运行Main方法,请求http://localhost:8080/,结果如下:
$ curl http://localhost:8080/
hello world
可以看到,项目运行成功。
接着,尝试使用jar包启动:
# 打包
mvn clean install -Dmaven.test.skip=true
# 启动jar包
java -jar target/springboot-parent-jar-1.0.0.jar
可以看到,项目启动成功,请求请求http://localhost:8080/,也能显示正确结果。
2. 非parent方式引入,打成jar包
在实际项目中,项目的parent依赖可能给了其他项目,此时parent引用就无法进行了,这时我们需要非parent引入。非parent引入的pom如下:
<?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
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gitee.funcy</groupId>
<artifactId>springboot-jar</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>springboot非parent jar打包方式</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-boot.version>2.1.1.RELEASE</spring-boot.version>
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<!-- 与parent引入相比,需要指定goals,否则会打包失败-->
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
再添加一个ControllerIndexController.java与启动类Main.java,这两个文件与上述示例相同,这里就不作展示了。
运行Main方法,请求http://localhost:8080/,结果如下:
$ curl http://localhost:8080/
hello world
可以看到,项目运行成功。
接着,尝试使用jar包启动:
# 打包
mvn clean install -Dmaven.test.skip=true
# 启动jar包
java -jar target/springboot-jar-1.0.0.jar
可以看到,项目启动成功,请求请求http://localhost:8080/,也能显示正确结果。
3. parent方式引入,打成war包
以上两种方式都是打成jar,为了兼容传统的servlet应用,springboot也支持打包war包,parent引入打包war包的pom文件如下:
<?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
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 引入springboot的parent -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
</parent>
<groupId>com.gitee.funcy</groupId>
<artifactId>springboot-parent-war</artifactId>
<version>1.0.0</version>
<!-- 指定打包方式为war包 -->
<packaging>war</packaging>
<name>springboot parent war打包方式</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<!-- 保持与 spring-boot-dependencies 版本一致 -->
<version>3.2.2</version>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
再添加一个ControllerIndexController.java与启动类Main.java,这两个文件与上述示例相同,这里就不作展示了。
除此之外,war包方式还需要添加一个类,用以实现SpringBootServletInitializer,该类与启动类Main.java位于同一个包下,主要是用来引导tomcat等servlet容器加载servlet,内容如下:
/**
* {这里添加描述}
*
* @author funcy
* @date 2019-12-20 1:22 下午
*/
public class StartApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
// 注意这里要指向原先用main方法执行的Application启动类
return builder.sources(Main.class);
}
}
运行Main方法,请求http://localhost:8080/,结果如下:
$ curl http://localhost:8080/
hello world
可以看到,项目运行成功。
接着,尝试使用jar包启动:
# 打包
mvn clean install -Dmaven.test.skip=true
# 启动jar包
java -jar target/springboot-parent-war-1.0.0.jar
可以看到,项目启动成功,请求请求http://localhost:8080/,也能显示正确结果。
4. 非parent方式引入,打成war包
同样地,打成war包时,也可使用非parent引入方式:
<?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
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gitee.funcy</groupId>
<artifactId>springboot-war</artifactId>
<version>1.0.0</version>
<!-- 指定打包方式为war包 -->
<packaging>war</packaging>
<name>springboot非parent war打包方式</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-boot.version>2.1.1.RELEASE</spring-boot.version>
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 测试war包中 WEB-INF/lib-provided/ 目录内容-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<!-- 打成war包时,需要添加该插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<!-- 保持与 spring-boot-dependencies 版本一致 -->
<version>3.2.2</version>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
再添加一个ControllerIndexController.java、StartApplication.java与启动类Main.java,这三个文件与上述示例相同,这里就不作展示了。
运行Main方法,请求http://localhost:8080/,结果如下:
$ curl http://localhost:8080/
hello world
可以看到,项目运行成功。
接着,尝试使用jar包启动:
# 打包
mvn clean install -Dmaven.test.skip=true
# 启动jar包
java -jar target/springboot-war-1.0.0.jar
可以看到,项目启动成功,请求请求http://localhost:8080/,也能显示正确结果。
5. 总结
springboot 引入及打包方式组合下来有如下四种:
| 打包/引入 | parent方式 | 非parent方式 |
|---|---|---|
| jar | parent-jar方式 | 非parent-jar方式 |
| war | parent-war方式 | 非parent-war方式 |