SpringBoot 打War问题

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, the spring-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 
    ......

猜你喜欢

转载自blog.csdn.net/IT_faquir/article/details/80726766
今日推荐