虽然Spring官方推荐springboot项目以jar包方式运行,但是在企业实际开发过程中,往往需要把项目打成war包运行,下面介绍springboot如何配置才能既打jar包又打war包。
1.创建一个springboot jar项目(自行百度,不再细说)
2.让springboot主程序类继承SpringBootServletInitializer,并重写configure方法。示例如下
@SpringBootApplication
public class DemospringApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(DemospringApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(DemospringApplication.class);
}
}
3.修改Springboot项目默认的pom配置(利用maven的profile配置打jar包和war包)
<?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.2.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demospring</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demospring</name>
<description>Demo project for Spring Boot</description>
<packaging>${project.packaging}</packaging>
<properties>
<java.version>1.8</java.version>
<!-- jar包名 -->
<jarFileName>demospring</jarFileName>
<!-- war包名 -->
<warFileName>demo_spring_web</warFileName>
<!-- release时间戳 yyyyMMdd-HHmmss为UTC时间 -->
<buildNumber>${maven.build.timestamp}</buildNumber>
<maven.build.timestamp.format>yyyyMMdd-HHmmss</maven.build.timestamp.format>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<!-- 利用maven的profiles可以灵活打jar包或war包 -->
<profiles>
<profile>
<!-- mvn clean install -Dmaven.test.skip=true -Pjar -->
<id>jar</id>
<!-- 激活这个profile为默认profile ,即默认clean install打jar包 -->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<project.packaging>jar</project.packaging>
</properties>
<build>
<finalName>${jarFileName}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<outputDirectory>./release/${buildNumber}</outputDirectory>
</configuration>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<configuration>
<tasks>
<copy todir="./release/${buildNumber}">
<fileset dir="${project.build.directory}">
<include name="${jarFileName}.jar"/>
</fileset>
</copy>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<!-- SpringBoot打war包,需要让主程序类 继承 SpringBootServletInitializer,并重写configure方法 -->
<profile>
<!-- mvn clean install -Dmaven.test.skip=true -Pwar -->
<id>war</id>
<properties>
<project.packaging>war</project.packaging>
</properties>
<dependencies>
<!-- 打war包要排除内嵌tomcat;并加上javax.servlet包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>${warFileName}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<outputDirectory>./release/${buildNumber}</outputDirectory>
</configuration>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<configuration>
<tasks>
<copy todir="./release/${buildNumber}">
<fileset dir="${project.build.directory}">
<include name="${warFileName}.war"/>
</fileset>
</copy>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
4.当项目需要打jar包时,执行命令
mvn clean install -Pjar
当需要打war包时,执行命令
mvn clean install -Pwar
上面的-Pjar 和-Pwar分别指定了maven打包时运行哪一个profile配置。
5.通过对以上2个命令的打包结果进行反编译探查,即可发现Springboot jar项目与war项目的区别
通过反编译可以看出SpringBoot打jar包时是没有WEB-INF,反而有一个BOOT-INF的目录,这是因为springboot以jar启动时用的是内置的tomcat容器,所以需要boot.loader作为启动器。另外,在打war包时会生成WEB-INF目录,因为外置tomcat服务器启动war项目时,会自动寻找WEB-INF目录,并且这里要单独引入servlet-api.jar才能让tomcat识别并启动Spring框架。