SpringBoot 打War问题
关于SpringBoot Maven相关介绍可参考:官方介绍及事例文档
https://docs.spring.io/spring-boot/docs/1.5.10.RELEASE/maven-plugin/usage.html
SpringBoot默认情况使用jar方式进行打包,并通过jar的方式来启动一个服务。
可以这样启动是因为Spring Boot内嵌了多种服务器,SpringBoot 1.5.14版本所支持的内置服务器如下:
Name | Servlet Version | Java Version |
---|---|---|
Tomcat 8 | 3.1 | Java 7+ |
Tomcat 7 | 3.0 | Java 6+ |
Jetty 9.3 | 3.1 | Java 8+ |
Jetty 9.2 | 3.1 | Java 7+ |
Jetty 8 | 3.0 | Java 6+ |
Undertow 1.3 | 3.1 | Java 7+ |
在很多场景下,需要通过外置服务器war包的形式运行。SpringBoot打成war包常常会遇坑,如打出的war包打不成功,打出的war包扔到服务器上跑不了等等问题。
1. POM配置
添加spring-boot-starter-parent依赖,该依赖只是一个POM文件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${boot.starter.version}</version>
<type>pom</type>
</dependency>
或者继承
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
官方文档上有这样一句话:
The spring-boot-starter-parent POM includes configuration to bind the repackage goal. If you are not using the parent POM you will need to declare this configuration yourself.
也就是说,项目中如果使用了spring-boot-starter-parent,其POM文件中已经为我们配置好了打包相关的MAVEN插件,否则的话需要自己在pom文件中声明插件,可如下配置:
<properties>
<start-class>team.seagull.bookbase.service.ServiceApplication</start-class>
</properties>
<build>
...
<plugins>
...
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>${start-class}</mainClass>
</configuration>
</plugin>
...
</build>
其中start-class占位符用于指明程序启动的入口,也就是SpringBoot中定义main方法的启动类。spring-boot-starter-parent中的占位符也为${start-class},为了让占位符有值,需要在properties中显示声明当前启动类,例如:
<properties>
<start-class>com.test.service.ServiceApplication</start-class>
</properties>
如果项目中有多个模块,需要在每个模块中声明打包方式,子模块声明为jar,主模块声明为war
如设置打包方式为jar,只需要pom中添加如下配置:
<packaging>jar</packaging>
如果是启动类所在模块,作为系统启动入口,需要将打包方式改为war。
2.依赖排除
- 排除内置tomcat容器
由于SpringBoot默认使用内置了tomcat容器,打包成war包需要将其排除。
<!-- 排除内置容器,排除内置容器导出成war包可以让外部容器运行spring-boot项目-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<optional>true</optional><!-- or <scope>provided</scope> -->
</dependency>
- 排除热部署
Devtools(热部署)默认被排除的,但有时为了提供开发效率将其引入,在开发过程中devtools会在类路径上的文件发生更改时自动重启,为代码更改提供了非常快的反馈循环
In order to make that work with war packaging, thespring-boot-devtools
dependency must be set as optional or with the provided scope.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>1.5.7.RELEASE</version>
<optional>true</optional><!-- or <scope>provided</scope> -->
</dependency>
3.指定Servlet初始化资源
在SpringBoot中没有了web.xml的配置,而是通过SpringBootServletInitializer在实现,其主要作用启动容器时负责加载相关配置。为了能够让容器识别到该启动类需要继承 SpringBootServletInitializer 并重写 configure 方法
@SpringBootApplication(scanBasePackages = {"com.example.testwar"})
public class DeployApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(DeployApplication.class, args);
}
/**
* 需要把web项目打成war包部署到外部tomcat运行时需要改变启动方式
*/
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(DeployApplication.class);
}
}
4.other
出现Could not register MBean for endpoint错误导致服务启动不了,可以在配置文件中,将Spring.jmx关闭,
spring:
jmx:
enabled: false
所报得异常:
o.s.b.a.e.jmx.EndpointMBeanExporter : Could not register MBean for endpoint [requestMappingEndpoint]
org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [org.springframework.boot.actuate.endpoint.jmx.AuditEventsJmxEndpoint@9a90bd3] with key 'auditEventsEndpoint'; nested exception is javax.management.InstanceAlreadyExistsException: bookClient:type=Endpoint,name=auditEventsEndpoint
at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:628) ~[spring-context-4.3.11.RELEASE.jar:4.3.11.RELEASE]
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.registerJmxEndpoints(EndpointMBeanExporter.java:174) [spring-boot-actuator-1.5.7.RELEASE.jar:1.5.7.RELEASE]
at
......